Documentation ¶
Overview ¶
Package jsonx is an extended JSON library for Go. It is highly tolerant of errors, and it supports trailing commas and comments (`//` and `/* ... */`).
It is ported from [Visual Studio Code's](https://github.com/Microsoft/vscode) comment-aware JSON parsing and editing APIs in TypeScript.
Index ¶
- func ApplyEdits(text string, edits ...Edit) (string, error)
- func ComputePropertyEdit(text string, path Path, value interface{}, ...) ([]Edit, []ParseErrorCode, error)
- func ComputePropertyRemoval(text string, path Path, options FormatOptions) ([]Edit, []ParseErrorCode, error)
- func NodeValue(node Node) interface{}
- func ObjectPropertyNames(node Node) []string
- func ParseTree(text string, options ParseOptions) (root *Node, errors []ParseErrorCode)
- func Walk(text string, options ParseOptions, visitor Visitor) bool
- type Edit
- type FormatOptions
- type Node
- type NodeType
- type ParseError
- type ParseErrorCode
- type ParseOptions
- type Path
- type ScanErrorCode
- type ScanOptions
- type Scanner
- type Segment
- type SyntaxKind
- type Visitor
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyEdits ¶
ApplyEdits applies the edits to the JSON document and returns the edited document. The edits must be ordered and within the bounds of the document.
func ComputePropertyEdit ¶
func ComputePropertyEdit(text string, path Path, value interface{}, insertionIndex func(properties []string) int, options FormatOptions) ([]Edit, []ParseErrorCode, error)
ComputePropertyEdit returns the edits necessary to set the value at the specified key path to the value. If value is nil, the property's value is set to JSON null; use ComputePropertyRemoval to obtain the edits necessary to remove a property. If value is a json.RawMessage, it is treated as an opaque value to insert (which means it can contain comments, trailing commas, etc.).
If the insertionIndex is non-nil, it is called to determine the index at which to insert the value (given the existing properties, in order).
func ComputePropertyRemoval ¶
func ComputePropertyRemoval(text string, path Path, options FormatOptions) ([]Edit, []ParseErrorCode, error)
ComputePropertyRemoval returns the edits necessary to remove the property at the specified key path.
func NodeValue ¶
func NodeValue(node Node) interface{}
NodeValue returns the JSON parse tree node's value.
func ObjectPropertyNames ¶
ObjectPropertyNames returns property names of the JSON object represented by the specified JSON parse tree node.
func ParseTree ¶
func ParseTree(text string, options ParseOptions) (root *Node, errors []ParseErrorCode)
ParseTree parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
Types ¶
type Edit ¶
type Edit struct { Offset int // the character offset where the edit begins Length int // the character length of the region to replace with the content Content string // the content to insert into the document }
An Edit represents an edit to a JSON document.
Example ¶
const input = ` /* comment */ { "a": 1 // oops! forgot a comma /* note the trailing comma */ "b": 2, }` // Insert value 3 at key path c/d. edits, _, _ := ComputePropertyEdit(input, PropertyPath("c", "d"), 3, nil, FormatOptions{InsertSpaces: true, TabSize: 2}, ) output, _ := ApplyEdits(input, edits...) fmt.Println(output)
Output: /* comment */ { "a": 1 // oops! forgot a comma /* note the trailing comma */ "b": 2, "c": { "d": 3 }, }
func Format ¶
func Format(text string, options FormatOptions) []Edit
Format returns edits that format the entire JSON document according to the format options. To apply the edits and obtain the formatted document content, use ApplyEdits.
func FormatEdit ¶
func FormatEdit(text string, edit Edit, options FormatOptions) ([]Edit, error)
FormatEdit returns the edits necessary to perform the original edit for maintaining the formatting of the JSON document.
func FormatRange ¶
func FormatRange(text string, offset, length int, options FormatOptions) []Edit
FormatRange returns edits that format the JSON document (starting at the character offset and continuing for the character length) according to the format options. To apply the edits and obtain the formatted document content, use ApplyEdits.
type FormatOptions ¶
type FormatOptions struct { TabSize int // If indentation is based on spaces (InsertSpaces == true), then what is the number of spaces that make an indent? InsertSpaces bool // Is indentation based on spaces? EOL string // The default end of line line character }
FormatOptions specifies formatting options.
type Node ¶
type Node struct { Type NodeType // the node's type Value interface{} // the node's value Offset int // character offset of the node's starting position in the document Length int // the length (in characters) of the node ColumnOffset int // character offset of the property's separator Parent *Node // the node's parent or nil if this is the root node Children []*Node // the node's children }
Node represents a node in a JSON document's parse tree.
func FindNodeAtLocation ¶
FindNodeAtLocation returns the node with the given key path under the JSON document parse tree root. If no such node exists, it returns nil.
type ParseError ¶
type ParseError struct { Code ParseErrorCode Offset int Length int }
func ParseWithDetailedErrors ¶
func ParseWithDetailedErrors(text string, options ParseOptions) ([]byte, []ParseError)
func (*ParseError) Error ¶
func (pe *ParseError) Error() string
type ParseErrorCode ¶
type ParseErrorCode int
A ParseErrorCode is a category of error that can occur while parsing a JSON document.
const ( InvalidSymbol ParseErrorCode = iota InvalidNumberFormat PropertyNameExpected ValueExpected ColonExpected CommaExpected CloseBraceExpected CloseBracketExpected EndOfFileExpected InvalidCommentToken // These get the ugly ParseError prefix because they conflict with existing // ScanErrorCode constants, and the ScanErrorCode constants existed first, // so we can't change them for BC reasons. ParseErrorUnexpectedEndOfComment ParseErrorUnexpectedEndOfString ParseErrorUnexpectedEndOfNumber ParseErrorInvalidUnicode ParseErrorInvalidEscapeCharacter ParseErrorInvalidCharacter // A catch all for an unexpected ScanErrorCode. InvalidScanErrorCode )
Parse error codes
func Parse ¶
func Parse(text string, options ParseOptions) ([]byte, []ParseErrorCode)
Parse the given text and returns the standard JSON representation of it, excluding the extensions supported by this package (such as comments and trailing commas).
On invalid input, the parser tries to be as fault tolerant as possible, but still return a result. Callers should check the errors list to see if the input was valid.
func (ParseErrorCode) String ¶
func (i ParseErrorCode) String() string
type ParseOptions ¶
type ParseOptions struct { Comments bool // allow comments (`//` and `/* ... */`) TrailingCommas bool // allow trailing commas in objects and arrays }
ParseOptions specifies options for JSON parsing.
type Path ¶
type Path []Segment
A Path is a JSON key path, which describes a path from an ancestor node in a JSON document's parse tree to one of its descendents.
func MakePath ¶
func MakePath(components ...interface{}) Path
MakePath returns a Path consisting of the specified components, each of which may be either a string (which is treated as a property segment) or an int (which is treated as an array index). Any other type causes it to panic.
func PropertyPath ¶
PropertyPath returns a Path consisting of the specified property names.
type ScanErrorCode ¶
type ScanErrorCode int
A ScanErrorCode is a category of error that can occur while scanning a JSON document.
const ( None ScanErrorCode = iota UnexpectedEndOfComment UnexpectedEndOfString UnexpectedEndOfNumber InvalidUnicode InvalidEscapeCharacter InvalidCharacter )
Scan error codes
func (ScanErrorCode) String ¶
func (i ScanErrorCode) String() string
type ScanOptions ¶
type ScanOptions struct {
Trivia bool // scan and emit whitespace and comment elements (false to ignore)
}
ScanOptions specifies options for NewScanner.
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
A Scanner scans a JSON document.
func NewScanner ¶
func NewScanner(text string, options ScanOptions) *Scanner
NewScanner creates a new scanner for the JSON document.
func (*Scanner) Err ¶
func (s *Scanner) Err() ScanErrorCode
Err returns the error code describing the error (if any) encountered while scanning the last-scanned token.
func (*Scanner) Scan ¶
func (s *Scanner) Scan() SyntaxKind
Scan scans and returns the next token from the input.
func (*Scanner) SetPosition ¶
SetPosition sets the scanner's position and resets its other internal state. Subsequent calls to Scan will start from the new position.
func (*Scanner) Token ¶
func (s *Scanner) Token() SyntaxKind
Token returns the kind of the last-scanned token.
func (*Scanner) TokenLength ¶
TokenLength returns the length of the last-scanned token.
func (*Scanner) TokenOffset ¶
TokenOffset returns the character offset of the last-scanned token.
type Segment ¶
type Segment struct { // IsProperty indicates the type of segment (true for property, false // for index). Because the zero values "" and 0 are valid values for the // Property and Index fields, this field is necessary to distinguish. IsProperty bool Property string // an object property name Index int // an array index }
A Segment is a component of a JSON key path. It is either an object property name or an array index.
func (Segment) MarshalJSON ¶
MarshalJSON implements json.Marshaler.
func (*Segment) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.
type SyntaxKind ¶
type SyntaxKind int
A SyntaxKind is a kind of syntax element in a JSON document.
const ( Unknown SyntaxKind = iota OpenBraceToken CloseBraceToken OpenBracketToken CloseBracketToken CommaToken ColonToken NullKeyword TrueKeyword FalseKeyword StringLiteral NumericLiteral LineCommentTrivia BlockCommentTrivia LineBreakTrivia Trivia EOF )
Syntax kinds
func (SyntaxKind) String ¶
func (i SyntaxKind) String() string
type Visitor ¶
type Visitor struct { // Invoked when an open brace is encountered and an object is started. The // offset and length represent the location of the open brace. OnObjectBegin func(offset, length int) // Invoked when a property is encountered. The offset and length represent // the location of the property name. OnObjectProperty func(property string, offset, length int) // Invoked when a closing brace is encountered and an object is completed. // The offset and length represent the location of the closing brace. OnObjectEnd func(offset, length int) // Invoked when an open bracket is encountered. The offset and length represent // the location of the open bracket. OnArrayBegin func(offset, length int) // Invoked when a closing bracket is encountered. The offset and length represent // the location of the closing bracket. OnArrayEnd func(offset, length int) // Invoked when a literal value is encountered. The offset and length represent // the location of the literal value. OnLiteralValue func(value interface{}, offset, length int) // Invoked when a comma or colon separator is encountered. The offset and length // represent the location of the separator. OnSeparator func(character rune, offset, length int) // Invoked on an error. OnError func(errorCode ParseErrorCode, offset, length int) }
A Visitor has its funcs invoked by Walk as it traverses the parse tree of a JSON document.