Documentation ¶
Overview ¶
Package hujson contains a parser and packer for the JWCC format: JSON With Commas and Comments (or "human JSON").
JWCC is an extension of standard JSON (as defined in RFC 8259) in order to make it more suitable for humans and configuration files. In particular, it supports line comments (e.g., //...), block comments (e.g., /*...*/), and trailing commas after the last member or element in a JSON object or array.
See https://nigeltao.github.io/blog/2021/json-with-commas-comments.html
Functionality ¶
The Parse function parses HuJSON input as a Value, which is a syntax tree exactly representing the input. Comments and whitespace are represented using the Extra type. Composite types in JSON are represented using the Object and Array types. Primitive types in JSON are represented using the Literal type. The Value.Pack method serializes the syntax tree as raw output, which is byte-for-byte identical to the input if no transformations were performed on the value.
A HuJSON value can be transformed using the Minimize, Standardize, Format, or Patch methods. Each of these methods mutate the value in place. Call the Clone method beforehand in order to preserve the original value. The Minimize and Standardize methods coerces HuJSON into standard JSON. The Format method formats the value; it is similar to `go fmt`, but instead for the HuJSON and standard JSON format. The Patch method applies a JSON Patch (RFC 6902) to the receiving value.
Grammar ¶
The changes to the JSON grammar are:
--- grammar.json +++ grammar.hujson @@ -1,13 +1,31 @@ members member + member ',' ws member ',' members elements element + element ',' ws element ',' elements +comments + "*/" + comment comments + +comment + '0000' . '10FFFF' + +linecomments + '\n' + linecomment linecomments + +linecomment + '0000' . '10FFFF' - '\n' + ws "" + "/*" comments + "//" linecomments '0020' ws '000A' ws '000D' ws
Use with the Standard Library ¶
This package operates with HuJSON as an AST. In order to parse HuJSON into arbitrary Go types, use this package to parse HuJSON input as an AST, strip the AST of any HuJSON-specific lexicographical elements, and then pack the AST as a standard JSON output.
Example usage:
b, err := hujson.Standardize(b) if err != nil { ... // handle err } if err := json.Unmarshal(b, &v); err != nil { ... // handle err }
Index ¶
- func Format(b []byte) ([]byte, error)
- func Minimize(b []byte) ([]byte, error)
- func Standardize(b []byte) ([]byte, error)
- type Array
- type ArrayElement
- type Extra
- type Kind
- type Literal
- type Object
- type ObjectMember
- type Value
- func (v *Value) All() iter.Seq[*Value]
- func (v Value) Clone() Value
- func (v *Value) Find(ptr string) *Value
- func (v *Value) Format()
- func (v Value) IsStandard() bool
- func (v *Value) Minimize()
- func (v Value) Pack() []byte
- func (v *Value) Patch(patch []byte) error
- func (v *Value) Range(f func(v *Value) bool) booldeprecated
- func (v *Value) Standardize()
- func (v Value) String() string
- func (v *Value) UpdateOffsets()
- type ValueTrimmed
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Format ¶
Format formats b according to some opinionated heuristics for how HuJSON should look. The exact output may change over time. It is the equivalent of `go fmt` but for HuJSON.
If the input is standard JSON, then the output will remain standard. Format is idempotent such that formatting already formatted HuJSON results in no changes. If an error is encountered, then b is returned as is along with the error.
func Minimize ¶
Minimize removes all whitespace, comments, and trailing commas from b, making it compliant with standard JSON per RFC 8259. If an error is encountered, then b is returned as is along with the error.
func Standardize ¶
Standardize strips any features specific to HuJSON from b, making it compliant with standard JSON per RFC 8259. All comments and trailing commas are replaced with a space character in order to preserve the original line numbers and byte offsets. If an error is encountered, then b is returned as is along with the error.
Types ¶
type Array ¶
type Array struct { // Elements are the elements of a JSON array. // A trailing comma is emitted only if the Value.AfterExtra // on the last value is non-nil. Otherwise it is omitted. Elements []ArrayElement // AfterExtra are the comments and whitespace // after the preceding open bracket or comma and before the closing bracket. AfterExtra Extra }
Array is an exact syntactic representation of a JSON array.
type ArrayElement ¶
type ArrayElement = Value
type Extra ¶
type Extra []byte
Extra is the raw bytes for whitespace and comments. Whitespace per RFC 8259, section 2 are permitted. Line comments that start with "//" and end with "\n" are permitted. Block comments that start with "/*" and end with "*/" are permitted.
func (Extra) IsStandard ¶
IsStandard reports whether this is standard JSON whitespace.
type Kind ¶
type Kind byte
Kind reports the kind of the JSON value. It is the first byte of the grammar for that JSON value, with the exception that JSON numbers are represented as a '0'.
'n': null 'f': false 't': true '"': string '0': number '{': object '[': array
type Literal ¶
type Literal []byte // e.g., null, false, true, "string", or 3.14159
Literal is the raw bytes for a JSON null, boolean, string, or number. It contains no surrounding whitespace or comments.
func Float ¶
Float construct a JSON literal for a floating-point number. The values NaN, +Inf, and -Inf will be represented as a JSON string with the values "NaN", "Infinity", and "-Infinity".
func String ¶
String constructs a JSON literal for string. Invalid UTF-8 is mangled with the Unicode replacement character.
func (Literal) Bool ¶
Bool returns the value for a JSON boolean. It returns false if the literal is not a JSON boolean.
func (Literal) Float ¶
Float returns the floating-point value for a JSON number. It returns a NaN, +Inf, or -Inf value for any JSON string with the values "NaN", "Infinity", or "-Infinity". It returns 0 for all other cases.
func (Literal) Int ¶
Int returns the signed integer value for a JSON number. It returns 0 if the literal is not a signed integer.
func (Literal) IsValid ¶
IsValid reports whether b is a valid JSON null, boolean, string, or number. The literal must not have surrounding whitespace.
func (Literal) Kind ¶
Kind represents each possible JSON literal kind with a single byte, which is conveniently the first byte of that kind's grammar with the restriction that numbers always be represented with '0'.
type Object ¶
type Object struct { // Members are the members of a JSON object. // A trailing comma is emitted only if the Value.AfterExtra // on the last value is non-nil. Otherwise it is omitted. Members []ObjectMember // AfterExtra are the comments and whitespace // after the preceding open brace or comma and before the closing brace. AfterExtra Extra }
Object is an exact syntactic representation of a JSON object.
type ObjectMember ¶
type ObjectMember struct {
Name, Value Value
}
type Value ¶
type Value struct { // BeforeExtra are the comments and whitespace before Value. // This is the extra after the preceding open brace, open bracket, // colon, comma, or start of input. BeforeExtra Extra // StartOffset is the offset of the first byte in Value. StartOffset int // Value is the JSON value without surrounding whitespace or comments. Value ValueTrimmed // EndOffset is the offset of the next byte after Value. EndOffset int // AfterExtra are the comments and whitespace after Value. // This is the extra before the succeeding colon, comma, or end of input. AfterExtra Extra }
Value is an exact syntactic representation of a JSON value. The starting and ending byte offsets are populated when parsing, but are otherwise ignored when packing.
By convention, code should operate on a non-pointer Value as a soft signal that the value should not be mutated, while operating on a pointer to Value to indicate that the value may be mutated. A non-pointer Value does not provide any language-enforced guarantees that it cannot be mutated. The Value.Clone method can be used to produce a deep copy of Value such that mutations on it will not be observed in the original Value.
func Parse ¶
Parse parses a HuJSON value as a Value. Extra and Literal values in v will alias the provided input buffer.
func (*Value) All ¶
All returns an iterator over all values in depth-first order, starting with v itself.
func (*Value) Find ¶
Find locates the value specified by the JSON pointer (see RFC 6901). It returns nil if the value does not exist or the pointer is invalid. If a JSON object has multiple members matching a given name, the first is returned. Object names are matched exactly, rather than with a case-insensitive match.
func (*Value) Format ¶
func (v *Value) Format()
Format formats the value according to some opinionated heuristics for how HuJSON should look. The exact output may change over time. It is the equivalent of `go fmt` but for HuJSON.
If the input is standard JSON, then the output will remain standard. Format is idempotent such that formatting already formatted HuJSON results in no changes.
func (Value) IsStandard ¶
IsStandard reports whether this is standard JSON by checking that there are no comments and no trailing commas.
func (*Value) Minimize ¶
func (v *Value) Minimize()
Minimize removes all whitespace, comments, and trailing commas from v, making it compliant with standard JSON per RFC 8259.
func (Value) Pack ¶
Pack serializes the value as HuJSON. The output is valid so long as every Extra and Literal in the Value is valid. The output does not alias the memory of any buffers referenced by v.
func (*Value) Patch ¶
Patch patches the value according to the provided patch file (per RFC 6902). The patch file may be in the HuJSON format where comments around and within a value being inserted are preserved. If the patch fails to fully apply, the receiver value will be left in a partially mutated state. Use Clone to preserve the original value.
It does not format the value. It is recommended that Format be called after applying a patch.
func (*Value) Standardize ¶
func (v *Value) Standardize()
Standardize strips any features specific to HuJSON from v, making it compliant with standard JSON per RFC 8259. All comments and trailing commas are replaced with a space character in order to preserve the original line numbers and byte offsets.
func (*Value) UpdateOffsets ¶
func (v *Value) UpdateOffsets()
UpdateOffsets iterates through v and updates all Value.StartOffset and Value.EndOffset fields so that they are accurate.
type ValueTrimmed ¶
type ValueTrimmed interface { // Kind reports the kind of the JSON value. Kind() Kind // contains filtered or unexported methods }
ValueTrimmed is a JSON value without surrounding whitespace or comments. This is a sum type consisting of Literal, *Object, or *Array.