json

package
v0.0.0-...-5f36cde Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 24 Imported by: 0

README

roundtrip/json

Package json provides a JSON, JSONC, and JSON5 parser that preserves source text trivia so documents can be decoded, inspected, edited, patched, and written back without discarding comments or formatting.

import "github.com/olimci/roundtrip/json"

Encoding and decoding

The high-level API mirrors the shape of encoding/json, but decode operations also return a *Meta tree that keeps the parsed source structure.

var dst any
m, err := json.Unmarshal(data, &dst)
out, err := json.Marshal(dst)
  • func Unmarshal(data []byte, v any) (*Meta, error) parses one strict JSON value, decodes it into v, and returns the roundtrippable metadata tree.
  • func Marshal(v any) ([]byte, error) encodes v as JSON.
  • func MarshalMeta(m *Meta) ([]byte, error) writes the exact bytes represented by a metadata tree using the tree's parsed syntax options.
  • type Marshaler interface { MarshalJSON() ([]byte, error) } is honored by encoders.
  • type Unmarshaler interface { UnmarshalJSON([]byte) error } is honored by decoders.
  • type RawMessage []byte implements MarshalJSON and UnmarshalJSON.
  • type Number string preserves a number literal. It provides String(), MarshalJSON(), Float64(), and Int64().

The encoder and decoder support the usual JSON struct tags:

  • field names from json:"name"
  • field exclusion with json:"-"
  • omitempty
  • omitzero, including IsZero() bool when available
  • string for quoted bool, integer, unsigned integer, float, and string values

Maps may use string, signed integer, unsigned integer, or encoding.TextMarshaler / encoding.TextUnmarshaler key types. Byte slices encode as base64 strings.

Streaming decoders

d := json.NewJSON5Decoder(r)
d.UseNumber()

var dst any
m, err := d.Decode(&dst)
  • func NewDecoder(r io.Reader) *Decoder creates a strict JSON decoder.
  • func NewJSONCDecoder(r io.Reader) *Decoder enables JSONC syntax options.
  • func NewJSON5Decoder(r io.Reader) *Decoder enables JSON5 syntax options.
  • func (d *Decoder) Decode(v any) (*Meta, error) decodes the next value from a stream and returns its metadata tree. Whitespace/comment-only input returns io.EOF.
  • func (d *Decoder) DecodeMeta() (*Meta, error) parses one value and requires end of input.
  • func (d *Decoder) UseNumber() decodes numbers in interface{} values as json.Number instead of float64.
  • func (d *Decoder) DisallowUnknownFields() rejects object members that do not match a destination struct field.
  • func (d *Decoder) More() bool reports whether another value or container element remains.
  • func (d *Decoder) Buffered() io.Reader returns buffered unread data.
  • func (d *Decoder) InputOffset() int64 returns the current input offset.
  • type Decoder struct { SyntaxOptions } embeds SyntaxOptions, so callers may configure individual syntax extensions directly.

Streaming encoders

e := json.NewEncoder(w)
e.SetIndent("", "  ")
e.SetEscapeHTML(false)
err := e.Encode(v)
  • func NewEncoder(w io.Writer) *Encoder creates a strict JSON encoder.
  • func NewJSON5Encoder(w io.Writer) *Encoder creates an encoder with JSON5 syntax options.
  • func (e *Encoder) Encode(v any) error writes one encoded value.
  • func (e *Encoder) EncodeMeta(m *Meta) error writes the exact bytes represented by m when they are valid for the encoder's syntax options.
  • func (e *Encoder) SetIndent(prefix, indent string) formats generated output.
  • func (e *Encoder) SetEscapeHTML(on bool) controls escaping of <, >, &, U+2028, and U+2029 in generated strings.
  • type Encoder struct { Indent string; Prefix string; SyntaxOptions } exposes the same formatting and syntax controls as fields.

When JSON5 syntax options are enabled, the encoder may emit unquoted ECMAScript identifier object keys, trailing commas, and IEEE 754 literals such as NaN and Infinity where applicable.

Syntax modes

SyntaxOptions controls optional syntax accepted by the parser and, where applicable, emitted by the encoder.

type SyntaxOptions struct {
	ECMAScriptIdentifiers          bool
	TrailingCommas                 bool
	SingleQuotedStrings            bool
	MultilineStrings               bool
	StringCharacterEscapes         bool
	HexadecimalNumbers             bool
	LeadingOrTrailingDecimalPoints bool
	LeadingPlusSigns               bool
	IEEE754Numbers                 bool
	SingleLineComments             bool
	MultilineComments              bool
	AdditionalWhitespace           bool
}
  • func JSONCSyntaxOptions() SyntaxOptions enables trailing commas and // / /* */ comments.
  • func JSON5SyntaxOptions() SyntaxOptions enables the full JSON5 option set.

Strict JSON is the zero value.

Metadata and nodes

Meta is the roundtrippable parse result. It owns the source token tree, the root node, and the detected indentation style.

m, err := json.NewJSONCDecoder(r).DecodeMeta()
root := m.Root()
  • type Meta struct { SST sst.SST[TokenType, NodeType]; Indent string } exposes the underlying syntax tree and detected indent string.
  • func (m *Meta) Clone() *Meta returns a detached copy of the metadata tree.
  • func (m *Meta) Root() Node returns the document root.
  • func (m *Meta) Nodes() iter.Seq[Node] walks all nodes.
  • func (m *Meta) Leaves() iter.Seq[Node] walks leaf nodes.
  • func (m *Meta) Comments() CommentSet returns comments before or after the root value.

Node is a handle into a Meta tree.

  • func (n Node) Type() NodeType returns the node kind.
  • func (n Node) Children() []Node returns wrapper nodes for child entries.
  • func (n Node) Bytes() []byte returns the original bytes for that node.
  • func (n Node) Clone() Node returns a detached copy of that node.
  • func (n Node) Decode(v any) error decodes the node into v.
  • func (n Node) Replace(v any) error replaces the node with an encoded Go value, another Node, or a *Meta.
  • func (n Node) Comments() CommentSet returns leading, trailing, and dangling comments attached to the node.
  • func (n Node) TrailingComment() (Comment, bool) returns the first trailing comment, if present.

Node kinds:

  • NodeTypeIllegal
  • NodeTypeObject
  • NodeTypeObjectField
  • NodeTypeArray
  • NodeTypeArrayElement
  • NodeTypeString
  • NodeTypeNumber
  • NodeTypeBool
  • NodeTypeNull

func (n NodeType) String() string returns the symbolic node kind.

Object editing

Object methods require a NodeTypeObject receiver unless noted.

  • func (n Node) ObjectField(name string) (Node, bool) returns the field value.
  • func (n Node) ObjectFieldNode(name string) (Node, bool) returns the NodeTypeObjectField wrapper.
  • func (n Node) ObjectFields() iter.Seq2[string, Node] iterates field names and field wrapper nodes.
  • func (n Node) Key() (Node, bool) returns an object field key node.
  • func (n Node) Value() (Node, bool) returns the value of an object field or array element wrapper.
  • func (n Node) ReplaceObjectField(name string, value any) error replaces an existing field value.
  • func (n Node) InsertObjectField(name string, value any) error appends a new field.
  • func (n Node) RemoveObjectField(name string) error removes a field.
  • func (n Node) RenameObjectField(oldName, newName string) error replaces a field key while preserving the field value and surrounding trivia.

Array editing

Array methods require a NodeTypeArray receiver unless noted.

  • func (n Node) ArrayValue(index int) (Node, bool) returns an element value.
  • func (n Node) ArrayElement(index int) (Node, bool) returns the NodeTypeArrayElement wrapper.
  • func (n Node) ReplaceArrayValue(index int, value any) error replaces an existing element value.
  • func (n Node) InsertArrayValue(index int, value any) error inserts before index; index == len(array) appends.
  • func (n Node) RemoveArrayValue(index int) error removes an element.

Path and JSON Pointer access

Path methods navigate with Go path segments:

  • string selects an object field value.
  • int selects an array value.
  • json.Append may be used only by insert operations to append to an array.
node, err := root.At("compilerOptions", "paths", 0)
err = root.InsertAt("new", "items", json.Append)
  • type AppendSegment struct{}
  • var Append AppendSegment
  • func (n Node) At(path ...any) (Node, error) reads a path.
  • func (n Node) ReplaceAt(value any, path ...any) error replaces a path.
  • func (n Node) InsertAt(value any, path ...any) error inserts at a path.
  • func (n Node) RemoveAt(path ...any) error removes a path.

JSON Pointer methods use RFC 6901 pointer strings:

  • func (n Node) JSONPointer(pointer string) (Node, error) reads a pointer.
  • func (n Node) ReplaceJSONPointer(pointer string, value any) error replaces a pointer target. The empty pointer replaces the receiver.
  • func (n Node) InsertJSONPointer(pointer string, value any) error inserts at a pointer target. /- appends to arrays.
  • func (n Node) RemoveJSONPointer(pointer string) error removes a pointer target.

Comments

Comments are available when the document was parsed with JSONC or JSON5 comment syntax enabled.

  • type Comment represents one source comment.
  • func (c Comment) Text() string returns the exact comment body without delimiters.
  • func (c Comment) ReplaceText(text string) error replaces the body while preserving the original comment style. Line comments reject embedded newlines.
  • type Comments []Comment
  • func (cs Comments) First() (Comment, bool) returns the first comment.
  • func (cs Comments) Text() string joins comment text with newlines.
  • type CommentSet struct { Leading, Trailing, Dangling Comments }
  • func (cs CommentSet) First() (Comment, bool) returns the first leading, dangling, or trailing comment.
  • func (cs CommentSet) Text() string joins all comment text in source order.
  • type CommentError struct { Err error; Token token; Text string } wraps comment replacement validation errors.

JSON Patch and Merge Patch

JSON Patch implements RFC 6902-style operations. Merge Patch implements RFC 7396-style object merging.

patches, err := json.DecodePatch(r)
err = meta.Patch(patches...)
  • type Patch struct { Op, Path, From string; Value any }
  • func DecodePatch(r io.Reader) ([]Patch, error) parses a JSON5 patch document.
  • func (target Node) Patch(patches ...Patch) error applies patches atomically to a target node.
  • func (m *Meta) Patch(patches ...Patch) error applies patches atomically to document root.
  • func (target Node) Merge(patch Node) error applies a merge patch atomically to a target node.
  • func (m *Meta) Merge(patch *Meta) error applies a merge patch atomically to the document root.

Supported patch operations are add, remove, replace, move, copy, and test. Patch Value may be a Go value, a Node, or a *Meta.

Formatting helpers

  • func Valid(data []byte) bool reports whether data is strict JSON.
  • func ValidWithOptions(data []byte, opts SyntaxOptions) bool reports whether data is valid for opts.
  • func Compact(dst *bytes.Buffer, src []byte) error removes whitespace from strict JSON input.
  • func CompactWithOptions(dst *bytes.Buffer, src []byte, opts SyntaxOptions) error removes whitespace from input accepted by opts while preserving comments.
  • func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error reformats strict JSON input while preserving trailing whitespace.
  • func IndentWithOptions(dst *bytes.Buffer, src []byte, prefix, indent string, opts SyntaxOptions) error reformats input accepted by opts while preserving comments and trailing whitespace.
  • func HTMLEscape(dst *bytes.Buffer, src []byte) escapes <, >, &, U+2028, and U+2029 inside JSON string literals.

Tokens

The syntax tree exposes token kinds through Meta.SST.

  • TokenAnchor
  • TokenIllegal
  • TokenEOF
  • TokenIdentifier
  • TokenNumber
  • TokenString
  • TokenColon
  • TokenComma
  • TokenDelim
  • TokenWhitespace
  • TokenNewline
  • TokenComment

func (t TokenType) String() string returns the symbolic token kind.

Errors

Parsing sentinel errors:

  • ErrUnexpectedEOF
  • ErrUnexpectedToken
  • ErrInvalidString
  • ErrInvalidNumber
  • ErrInvalidSpace
  • ErrDuplicateObjectKey

Tree editing sentinel errors:

  • ErrWrongNodeType
  • ErrObjectFieldNotFound
  • ErrObjectFieldExists
  • ErrArrayIndexOutOfRange

Path sentinel errors:

  • ErrEmptyPath
  • ErrInvalidPathSegment
  • ErrInvalidJSONPointer
  • ErrInvalidAppend

Comment sentinel errors:

  • ErrInvalidComment

Patch sentinel errors:

  • ErrInvalidPatch
  • ErrInvalidPatchOperation
  • ErrPatchTestFailed

Structured error types:

  • type ParseError struct { Err error; Token token } reports syntax failures with source position and supports errors.Is through Unwrap.
  • type PathError struct { Op string; Index int; Segment any; Err error } reports path, pointer, and patch operation failures and supports errors.Is through Unwrap.
  • type CommentError struct { Err error; Token token; Text string } reports invalid comment replacement text and supports errors.Is through Unwrap.
  • type SyntaxError struct { Offset int64 } matches the standard library error shape.
  • type UnmarshalTypeError struct { Value string; Type reflect.Type; Offset int64; Struct string; Field string } reports incompatible decode targets.
  • type InvalidUnmarshalError struct { Type reflect.Type } reports invalid decode destinations.
  • type UnsupportedTypeError struct { Type reflect.Type }
  • type UnsupportedValueError struct { Value reflect.Value; Str string }
  • type MarshalerError struct { Type reflect.Type; Err error } wraps errors returned by MarshalJSON.

Documentation

Overview

Package json encodes, decodes, formats, and edits JSON while preserving the source document's syntax tree, whitespace, and comments.

Decoding returns a *Meta alongside the decoded Go value. Meta and the Node values derived from it are live handles into the parsed document. Mutating a Node mutates its owning Meta. Node values are not detached snapshots; use MarshalMeta or EncodeMeta to observe the current document bytes.

Unless a function states otherwise, pointer parameters must be non-nil and Node or Comment receivers must have been obtained from this package. A zero Node or Comment is not a valid receiver.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnexpectedEOF reports input that ended before a complete value was parsed.
	ErrUnexpectedEOF = errors.New("unexpected EOF")
	// ErrUnexpectedToken reports a token that is not valid at the current parse position.
	ErrUnexpectedToken = errors.New("unexpected token")
	// ErrInvalidString reports a malformed string literal.
	ErrInvalidString = errors.New("invalid string")
	// ErrInvalidNumber reports a malformed number literal.
	ErrInvalidNumber = errors.New("invalid number")
	// ErrInvalidSpace reports whitespace that is not valid for the active syntax options.
	ErrInvalidSpace = errors.New("invalid whitespace")
	// ErrDuplicateObjectKey reports an object key repeated in the same object.
	ErrDuplicateObjectKey = errors.New("duplicate object key")
)
View Source
var (
	// ErrWrongNodeType reports an operation applied to the wrong JSON node type.
	ErrWrongNodeType = errors.New("wrong node type")
	// ErrObjectFieldNotFound reports a missing object field.
	ErrObjectFieldNotFound = errors.New("object field not found")
	// ErrObjectFieldExists reports an object insertion for a field that already exists.
	ErrObjectFieldExists = errors.New("object field exists")
	// ErrArrayIndexOutOfRange reports an array index outside the supported range.
	ErrArrayIndexOutOfRange = errors.New("array index out of range")
)
View Source
var (
	// ErrInvalidPatch reports a patch document that is not a valid patch array.
	ErrInvalidPatch = errors.New("invalid JSON patch")
	// ErrInvalidPatchOperation reports an invalid operation inside a patch document.
	ErrInvalidPatchOperation = errors.New("invalid JSON patch operation")
	// ErrPatchTestFailed reports a failed JSON Patch test operation.
	ErrPatchTestFailed = errors.New("JSON patch test failed")
)
View Source
var (
	// ErrEmptyPath reports a mutation operation that requires at least one path segment.
	ErrEmptyPath = errors.New("empty path")
	// ErrInvalidPathSegment reports a path segment with an unsupported type or value.
	ErrInvalidPathSegment = errors.New("invalid path segment")
	// ErrInvalidJSONPointer reports a malformed RFC 6901 JSON Pointer.
	ErrInvalidJSONPointer = errors.New("invalid JSON pointer")
	// ErrInvalidAppend reports use of the append marker outside array insertion.
	ErrInvalidAppend = errors.New("invalid append segment")
)
View Source
var ErrInvalidComment = errors.New("invalid comment")

ErrInvalidComment reports replacement text that cannot fit the existing comment form.

Functions

func Compact

func Compact(dst *bytes.Buffer, src []byte) error

Compact appends src to dst with insignificant whitespace removed.

dst must be non-nil. Compact accepts strict JSON.

func CompactWithOptions

func CompactWithOptions(dst *bytes.Buffer, src []byte, opts SyntaxOptions) error

CompactWithOptions appends src to dst with insignificant whitespace removed.

dst must be non-nil. CompactWithOptions accepts syntax enabled by opts and preserves comments.

func HTMLEscape

func HTMLEscape(dst *bytes.Buffer, src []byte)

HTMLEscape appends src to dst with HTML-significant characters escaped inside JSON strings.

dst must be non-nil.

func Indent

func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error

Indent appends an indented form of src to dst.

dst must be non-nil. Indent accepts strict JSON.

func IndentWithOptions

func IndentWithOptions(dst *bytes.Buffer, src []byte, prefix, indent string, opts SyntaxOptions) error

IndentWithOptions appends an indented form of src to dst.

dst must be non-nil. IndentWithOptions accepts syntax enabled by opts and preserves comments.

func Marshal

func Marshal(v any) ([]byte, error)

Marshal encodes v as JSON.

func MarshalMeta

func MarshalMeta(m *Meta) ([]byte, error)

MarshalMeta returns the current bytes represented by m.

m must be non-nil.

func Valid

func Valid(data []byte) bool

Valid reports whether data is a complete strict JSON value.

func ValidWithOptions

func ValidWithOptions(data []byte, opts SyntaxOptions) bool

ValidWithOptions reports whether data is a complete JSON value for opts.

Types

type AppendSegment

type AppendSegment struct{}

AppendSegment marks an array append operation in InsertAt paths.

var Append AppendSegment

Append appends to an array when used as the final segment of InsertAt.

type Comment

type Comment struct {
	// contains filtered or unexported fields
}

Comment is a live handle to one source comment token.

Copying a Comment copies the handle. Mutating a Comment updates its owning Meta. A zero Comment is not a valid receiver.

func (Comment) ReplaceText

func (c Comment) ReplaceText(text string) error

ReplaceText replaces the comment text while preserving the existing comment form.

func (Comment) Text

func (c Comment) Text() string

Text returns the comment text without the comment delimiters.

type CommentError

type CommentError struct {
	Err   error
	Token token
	Text  string
}

CommentError describes an invalid comment replacement.

func (CommentError) Error

func (e CommentError) Error() string

Error returns the formatted comment error.

func (CommentError) Unwrap

func (e CommentError) Unwrap() error

Unwrap returns the underlying comment error.

type CommentSet

type CommentSet struct {
	Leading  Comments
	Trailing Comments
	Dangling Comments
}

CommentSet groups comments by their relationship to a node.

func (CommentSet) First

func (cs CommentSet) First() (Comment, bool)

First returns the first leading, dangling, or trailing comment in that order.

func (CommentSet) Text

func (cs CommentSet) Text() string

Text joins all comments in leading, dangling, then trailing order.

type Comments

type Comments []Comment

Comments is an ordered group of comment handles.

func (Comments) First

func (cs Comments) First() (Comment, bool)

First returns the first comment in cs.

func (Comments) Text

func (cs Comments) Text() string

Text joins the text of each comment in source order with newlines.

type Decoder

type Decoder struct {
	SyntaxOptions
	// contains filtered or unexported fields
}

Decoder reads JSON values from an input stream.

A Decoder is stateful and not safe for concurrent use. Its methods require a non-nil *Decoder returned by NewDecoder, NewJSONCDecoder, or NewJSON5Decoder.

func NewDecoder

func NewDecoder(r io.Reader) *Decoder

NewDecoder returns a decoder that reads strict JSON from r.

r must be non-nil and must remain usable for the lifetime of the Decoder.

func NewJSON5Decoder

func NewJSON5Decoder(r io.Reader) *Decoder

NewJSON5Decoder returns a decoder that reads JSON5 from r.

r must be non-nil and must remain usable for the lifetime of the Decoder.

func NewJSONCDecoder

func NewJSONCDecoder(r io.Reader) *Decoder

NewJSONCDecoder returns a decoder that reads JSONC from r.

r must be non-nil and must remain usable for the lifetime of the Decoder.

func (*Decoder) Buffered

func (d *Decoder) Buffered() io.Reader

Buffered returns a reader for bytes already read from the underlying reader but not consumed by the decoder.

func (*Decoder) Decode

func (d *Decoder) Decode(v any) (*Meta, error)

Decode reads the next JSON value, stores it in v, and returns its metadata tree.

v must be a non-nil pointer. At the end of a stream, Decode returns io.EOF.

func (*Decoder) DecodeMeta

func (d *Decoder) DecodeMeta() (*Meta, error)

DecodeMeta reads one complete JSON value and returns its metadata tree.

func (*Decoder) DisallowUnknownFields

func (d *Decoder) DisallowUnknownFields()

DisallowUnknownFields causes Decode to reject object keys that do not match a destination struct field.

func (*Decoder) InputOffset

func (d *Decoder) InputOffset() int64

InputOffset returns the byte offset of the decoder's current input position.

func (*Decoder) More

func (d *Decoder) More() bool

More reports whether another element is available in the current array or object being decoded.

func (*Decoder) UseNumber

func (d *Decoder) UseNumber()

UseNumber causes Decode and Unmarshal to store numbers in interface values as Number instead of float64.

type Encoder

type Encoder struct {
	Indent string
	Prefix string

	SyntaxOptions
	// contains filtered or unexported fields
}

Encoder writes JSON values to an output stream.

An Encoder is stateful and not safe for concurrent use. Its methods require a non-nil *Encoder returned by NewEncoder or NewJSON5Encoder.

func NewEncoder

func NewEncoder(w io.Writer) *Encoder

NewEncoder returns an encoder that writes strict JSON to w.

w must be non-nil and must remain usable for the lifetime of the Encoder.

func NewJSON5Encoder

func NewJSON5Encoder(w io.Writer) *Encoder

NewJSON5Encoder returns an encoder that writes JSON5-compatible output to w.

w must be non-nil and must remain usable for the lifetime of the Encoder.

func (*Encoder) Encode

func (e *Encoder) Encode(v any) error

Encode writes v as one JSON value.

func (*Encoder) EncodeMeta

func (e *Encoder) EncodeMeta(m *Meta) error

EncodeMeta writes the current bytes represented by m.

m must be non-nil.

func (*Encoder) SetEscapeHTML

func (e *Encoder) SetEscapeHTML(on bool)

SetEscapeHTML controls whether string values escape HTML-significant characters.

func (*Encoder) SetIndent

func (e *Encoder) SetIndent(prefix, indent string)

SetIndent configures the prefix and indentation used for subsequent Encode calls.

type InvalidUnmarshalError

type InvalidUnmarshalError struct {
	Type reflect.Type
}

InvalidUnmarshalError describes an invalid target passed to Unmarshal, Decoder.Decode, or Node.Decode.

Those APIs require v to be a non-nil pointer to the value being populated.

func (InvalidUnmarshalError) Error

func (e InvalidUnmarshalError) Error() string

Error returns the formatted invalid unmarshal target error.

type Marshaler

type Marshaler interface {
	MarshalJSON() ([]byte, error)
}

Marshaler is implemented by values that encode their own JSON representation.

MarshalJSON must return one complete JSON value. Pointer receiver implementations are called only when the source value is addressable.

type MarshalerError

type MarshalerError struct {
	Type       reflect.Type
	Err        error
	SourceFunc string
}

MarshalerError wraps an error returned by a Marshaler implementation.

func (*MarshalerError) Error

func (e *MarshalerError) Error() string

Error returns the formatted marshaler error.

func (*MarshalerError) Unwrap

func (e *MarshalerError) Unwrap() error

Unwrap returns the error reported by the Marshaler.

type Meta

type Meta struct {
	SST    sst.SST[TokenType, NodeType]
	Indent string
	// contains filtered or unexported fields
}

Meta owns a parsed JSON document and its preserved syntax metadata.

Meta values are mutable and not safe for concurrent use. Methods on *Meta require a non-nil pointer returned by this package.

func Unmarshal

func Unmarshal(data []byte, v any) (*Meta, error)

Unmarshal parses one JSON value from data, stores it in v, and returns the parsed metadata tree.

v must be a non-nil pointer. The returned *Meta owns the parsed document; Nodes obtained from it remain live handles into that Meta.

func (*Meta) Clone

func (m *Meta) Clone() *Meta

Clone returns a detached copy of m.

The returned Meta preserves m's syntax options, indentation, tokens, comments, and tree shape. Mutating either Meta does not affect the other.

func (*Meta) Comments

func (m *Meta) Comments() CommentSet

Comments returns comments adjacent to the document root.

m must be non-nil. Returned Comment values are live handles into m.

func (*Meta) Leaves

func (m *Meta) Leaves() iter.Seq[Node]

Leaves iterates over leaf nodes in source order.

m must be non-nil. Yielded Node values are live handles into m.

func (*Meta) Merge

func (m *Meta) Merge(patch *Meta) error

Merge applies an RFC 7396 JSON Merge Patch to m.

m and patch must be non-nil. The patch document is read but not mutated.

func (*Meta) Nodes

func (m *Meta) Nodes() iter.Seq[Node]

Nodes iterates over every node in source order.

m must be non-nil. Yielded Node values are live handles into m.

func (*Meta) Patch

func (m *Meta) Patch(patches ...Patch) error

Patch applies RFC 6902 JSON Patch operations to m atomically.

m must be non-nil. If an operation fails, m is unchanged.

func (*Meta) Root

func (m *Meta) Root() Node

Root returns a live handle to the document root.

m must be non-nil.

type Node

type Node struct {
	// contains filtered or unexported fields
}

Node is a live handle to one node in a Meta syntax tree.

Copying a Node copies the handle, not the underlying syntax tree. Mutating methods update the owning Meta. A zero Node is not a valid receiver.

func (Node) ArrayElement

func (n Node) ArrayElement(index int) (Node, bool)

ArrayElement returns the array-element wrapper node at index.

The returned Node is a live handle into the same Meta.

func (Node) ArrayValue

func (n Node) ArrayValue(index int) (Node, bool)

ArrayValue returns the value at index in an array.

The returned Node is a live handle into the same Meta.

func (Node) At

func (n Node) At(path ...any) (Node, error)

At follows path from this node and returns the addressed node.

String segments select object fields, int segments select array indexes, and Append is invalid for access. The returned Node is a live handle into the same Meta.

func (Node) Bytes

func (n Node) Bytes() []byte

Bytes returns the current source bytes for this node.

func (Node) Children

func (n Node) Children() []Node

Children returns handles for this node's direct children.

The returned slice is a snapshot of child handles. Each Node in it remains a live handle into the same Meta.

func (Node) Clone

func (n Node) Clone() Node

Clone returns a detached copy of this node.

The returned Node is a live handle into a new Meta. Mutating either node does not affect the other.

func (Node) Comments

func (n Node) Comments() CommentSet

Comments returns comments adjacent to this node.

Returned Comment values are live handles into the same Meta.

func (Node) Decode

func (n Node) Decode(v any) error

Decode stores this node's JSON value in v.

v must be a non-nil pointer.

func (Node) InsertArrayValue

func (n Node) InsertArrayValue(index int, value any) error

InsertArrayValue inserts value before index in an array.

index may equal the current array length to append. If value is a Node or *Meta, its current JSON value is cloned into this node's owning Meta.

func (Node) InsertAt

func (n Node) InsertAt(value any, path ...any) error

InsertAt inserts value at path.

The final path segment may be Append to append to an array. If value is a Node or *Meta, its current JSON value is cloned into this node's owning Meta.

func (Node) InsertJSONPointer

func (n Node) InsertJSONPointer(pointer string, value any) error

InsertJSONPointer inserts value at an RFC 6901 JSON Pointer.

A final "-" token appends to an array. If value is a Node or *Meta, its current JSON value is cloned into this node's owning Meta.

func (Node) InsertObjectField

func (n Node) InsertObjectField(name string, value any) error

InsertObjectField appends a new object field.

If value is a Node or *Meta, its current JSON value is cloned into this node's owning Meta.

func (Node) JSONPointer

func (n Node) JSONPointer(pointer string) (Node, error)

JSONPointer follows an RFC 6901 JSON Pointer from this node.

The returned Node is a live handle into the same Meta.

func (Node) Key

func (n Node) Key() (Node, bool)

Key returns the key node for an object-field wrapper node.

func (Node) Merge

func (target Node) Merge(patch Node) error

Merge applies an RFC 7396 JSON Merge Patch to target.

target and patch must be valid Nodes. The patch value is read from its owning Meta and cloned into target's owning Meta as needed.

func (Node) ObjectField

func (n Node) ObjectField(name string) (Node, bool)

ObjectField returns the value for object field name.

The returned Node is a live handle into the same Meta.

func (Node) ObjectFieldNode

func (n Node) ObjectFieldNode(name string) (Node, bool)

ObjectFieldNode returns the object-field wrapper node for name.

The returned Node is a live handle into the same Meta.

func (Node) ObjectFields

func (n Node) ObjectFields() iter.Seq2[string, Node]

ObjectFields iterates over this object's fields in source order.

Yielded Nodes are object-field wrapper nodes and are live handles into the same Meta. Non-object receivers yield nothing.

func (Node) Patch

func (target Node) Patch(patches ...Patch) error

Patch applies RFC 6902 JSON Patch operations to target atomically.

If an operation fails, target is unchanged.

func (Node) RemoveArrayValue

func (n Node) RemoveArrayValue(index int) error

RemoveArrayValue removes the array value at index.

func (Node) RemoveAt

func (n Node) RemoveAt(path ...any) error

RemoveAt removes the node addressed by path.

func (Node) RemoveJSONPointer

func (n Node) RemoveJSONPointer(pointer string) error

RemoveJSONPointer removes the node addressed by an RFC 6901 JSON Pointer.

func (Node) RemoveObjectField

func (n Node) RemoveObjectField(name string) error

RemoveObjectField removes an existing object field.

func (Node) RenameObjectField

func (n Node) RenameObjectField(oldName, newName string) error

RenameObjectField changes an existing object field's key.

func (Node) Replace

func (n Node) Replace(v any) error

Replace replaces this node with v.

If v is a Node or *Meta, its current JSON value is cloned into this node's owning Meta; later mutations to v's original owner do not affect this node.

func (Node) ReplaceArrayValue

func (n Node) ReplaceArrayValue(index int, value any) error

ReplaceArrayValue replaces the array value at index.

func (Node) ReplaceAt

func (n Node) ReplaceAt(value any, path ...any) error

ReplaceAt replaces the node addressed by path.

An empty path replaces the receiver. If value is a Node or *Meta, its current JSON value is cloned into this node's owning Meta.

func (Node) ReplaceJSONPointer

func (n Node) ReplaceJSONPointer(pointer string, value any) error

ReplaceJSONPointer replaces the node addressed by an RFC 6901 JSON Pointer.

An empty pointer replaces the receiver. If value is a Node or *Meta, its current JSON value is cloned into this node's owning Meta.

func (Node) ReplaceObjectField

func (n Node) ReplaceObjectField(name string, value any) error

ReplaceObjectField replaces the value for an existing object field.

func (Node) TrailingComment

func (n Node) TrailingComment() (Comment, bool)

TrailingComment returns the first trailing comment adjacent to this node.

The returned Comment is a live handle into the same Meta.

func (Node) Type

func (n Node) Type() NodeType

Type returns the JSON node type.

func (Node) Value

func (n Node) Value() (Node, bool)

Value returns the value node for an object-field or array-element wrapper node.

type NodeType

type NodeType int8

NodeType identifies a node in the parsed JSON syntax tree.

const (
	// NodeTypeIllegal identifies an invalid node.
	NodeTypeIllegal NodeType = iota
	// NodeTypeObject identifies a JSON object.
	NodeTypeObject
	// NodeTypeObjectField identifies an object field wrapper node.
	NodeTypeObjectField
	// NodeTypeArray identifies a JSON array.
	NodeTypeArray
	// NodeTypeArrayElement identifies an array element wrapper node.
	NodeTypeArrayElement
	// NodeTypeString identifies a string value.
	NodeTypeString
	// NodeTypeNumber identifies a number value.
	NodeTypeNumber
	// NodeTypeBool identifies a boolean value.
	NodeTypeBool
	// NodeTypeNull identifies null.
	NodeTypeNull
)

func (NodeType) String

func (n NodeType) String() string

String returns the display name for n.

type Number

type Number string

Number stores a JSON number literal without converting it to float64.

func (Number) Float64

func (n Number) Float64() (float64, error)

Float64 converts n to a float64.

func (Number) Int64

func (n Number) Int64() (int64, error)

Int64 converts n to an int64.

func (Number) MarshalJSON

func (n Number) MarshalJSON() ([]byte, error)

MarshalJSON returns n as one JSON number.

func (Number) String

func (n Number) String() string

String returns the number literal.

type ParseError

type ParseError struct {
	Err   error
	Token token
}

ParseError describes a lexer or parser error at a concrete input token.

func (ParseError) Error

func (e ParseError) Error() string

Error returns the formatted parse error.

func (ParseError) Unwrap

func (e ParseError) Unwrap() error

Unwrap returns the underlying parse error sentinel.

type Patch

type Patch struct {
	Op    string
	Path  string
	From  string
	Value any
}

Patch is one RFC 6902 JSON Patch operation.

Value may be a plain Go value, Node, or *Meta. When Value is a Node or *Meta, the operation clones its current JSON value before inserting it into the target.

func DecodePatch

func DecodePatch(r io.Reader) ([]Patch, error)

DecodePatch reads RFC 6902 JSON Patch operations from r.

r must be non-nil. Patch values decoded from the "value" field are live Nodes owned by the temporary Meta built while decoding.

type PathError

type PathError struct {
	Op      string
	Index   int
	Segment any
	Err     error
}

PathError describes an error while applying a path or JSON Pointer operation.

func (*PathError) Error

func (e *PathError) Error() string

Error returns the formatted path error.

func (*PathError) Unwrap

func (e *PathError) Unwrap() error

Unwrap returns the underlying path error.

type RawMessage

type RawMessage []byte

RawMessage is a raw encoded JSON value.

MarshalJSON emits nil RawMessage values as null. UnmarshalJSON requires a non-nil *RawMessage receiver and replaces the receiver's bytes with a copy of data.

func (RawMessage) MarshalJSON

func (m RawMessage) MarshalJSON() ([]byte, error)

MarshalJSON returns m as one encoded JSON value.

func (*RawMessage) UnmarshalJSON

func (m *RawMessage) UnmarshalJSON(data []byte) error

UnmarshalJSON replaces m with a copy of data.

m must be non-nil.

type SyntaxError

type SyntaxError struct {
	Offset int64
	// contains filtered or unexported fields
}

SyntaxError describes invalid JSON syntax.

func (*SyntaxError) Error

func (e *SyntaxError) Error() string

Error returns the formatted syntax error.

type SyntaxOptions

type SyntaxOptions struct {
	// ECMAScriptIdentifiers allows unquoted object keys that are valid
	// ECMAScript identifiers.
	ECMAScriptIdentifiers bool
	// TrailingCommas allows a comma after the final array element or object field.
	TrailingCommas bool
	// SingleQuotedStrings allows strings quoted with single quotes.
	SingleQuotedStrings bool
	// MultilineStrings allows line continuations inside string literals.
	MultilineStrings bool
	// StringCharacterEscapes allows JSON5 character escapes that strict JSON
	// does not permit.
	StringCharacterEscapes bool
	// HexadecimalNumbers allows hexadecimal number literals.
	HexadecimalNumbers bool
	// LeadingOrTrailingDecimalPoints allows number literals such as .1 and 1.
	LeadingOrTrailingDecimalPoints bool
	// LeadingPlusSigns allows a leading plus sign on number literals.
	LeadingPlusSigns bool
	// IEEE754Numbers allows Infinity, -Infinity, and NaN number literals.
	IEEE754Numbers bool
	// SingleLineComments allows // comments.
	SingleLineComments bool
	// MultilineComments allows block comments.
	MultilineComments bool
	// AdditionalWhitespace allows JSON5 whitespace beyond strict JSON's space,
	// tab, carriage return, and line feed.
	AdditionalWhitespace bool
}

SyntaxOptions controls optional JSON syntax extensions accepted by the decoder and, where applicable, emitted by the encoder.

func JSON5SyntaxOptions

func JSON5SyntaxOptions() SyntaxOptions

JSON5SyntaxOptions returns the full set of JSON5 syntax extensions.

func JSONCSyntaxOptions

func JSONCSyntaxOptions() SyntaxOptions

JSONCSyntaxOptions returns the syntax extensions commonly used by JSONC.

type TokenType

type TokenType int8

TokenType identifies a lexical token in preserved source text.

const (
	// TokenAnchor is an internal zero-width marker used to delimit nodes.
	TokenAnchor TokenType = -1
	// TokenIllegal identifies an invalid token.
	TokenIllegal TokenType = iota
	// TokenEOF identifies the end of input.
	TokenEOF
	// TokenIdentifier identifies JSON identifiers such as true, false, null, or JSON5 names.
	TokenIdentifier
	// TokenNumber identifies a number literal.
	TokenNumber
	// TokenString identifies a string literal.
	TokenString
	// TokenColon identifies a colon.
	TokenColon
	// TokenComma identifies a comma.
	TokenComma
	// TokenDelim identifies a brace or bracket delimiter.
	TokenDelim
	// TokenWhitespace identifies horizontal whitespace.
	TokenWhitespace
	// TokenNewline identifies a newline.
	TokenNewline
	// TokenComment identifies a line or block comment.
	TokenComment
)

func (TokenType) String

func (t TokenType) String() string

String returns the display name for t.

type UnmarshalTypeError

type UnmarshalTypeError struct {
	Value  string
	Type   reflect.Type
	Offset int64
	Struct string
	Field  string
}

UnmarshalTypeError describes a JSON value that cannot be assigned to the requested Go type.

func (*UnmarshalTypeError) Error

func (e *UnmarshalTypeError) Error() string

Error returns the formatted unmarshal type error.

type Unmarshaler

type Unmarshaler interface {
	UnmarshalJSON([]byte) error
}

Unmarshaler is implemented by values that decode their own JSON representation.

UnmarshalJSON receives the exact bytes for the value being decoded. Pointer receiver implementations are called only when the target value is addressable.

type UnsupportedTypeError

type UnsupportedTypeError struct {
	Type reflect.Type
}

UnsupportedTypeError describes a Go type that cannot be encoded as JSON.

func (*UnsupportedTypeError) Error

func (e *UnsupportedTypeError) Error() string

Error returns the formatted unsupported type error.

type UnsupportedValueError

type UnsupportedValueError struct {
	Value reflect.Value
	Str   string
}

UnsupportedValueError describes a Go value that cannot be encoded as JSON.

func (*UnsupportedValueError) Error

func (e *UnsupportedValueError) Error() string

Error returns the formatted unsupported value error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL