jsonvx

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 1, 2025 License: MIT Imports: 8 Imported by: 0

README

JSONVX

jsonvx is a highly configurable JSON parser, querier, and formatter for Go.

It supports both strict JSON (as defined by ECMA-404) and up to a more relaxed variant such as JSON5. This makes it ideal for parsing user-generated data, configuration files, or legacy formats that don't fully comply with the JSON specification.

With a single ParserConfig struct, jsonvx gives you fine-grained control over how JSON is parsed. You can enable or disable features like:

After parsing, jsonvx gives you a clean abstract syntax tree (AST) that you can either traverse manually or query using the built-in API. Each node in the tree implements a common JSON interface, so you can safely inspect, transform, or stringify data as needed.

jsonvx is designed for flexibility and correctness — not raw performance. It prioritizes clarity and configurability over speed, making it perfect for tools, linters, formatters, and config loaders where input may vary or include non-standard extensions.

If you need full control over how JSON is interpreted and a structured way to work with the result, jsonvx is for you.

Installing

To start using jsonvx, install Go and run go get:

$ go get -u github.com/bube054/jsonvx

Quick Start

Get up and running with jsonvx in seconds. Just create a new Parser, parse your JSON, and access fields using a simple path query system.

package main

import (
	"fmt"

	"github.com/your/module/jsonvx"
)

func main() {
	data := []byte(`{
		"name": {"first": "Tom", "last": "Anderson"},
		"age": 37,
		"children": ["Sara", "Alex", "Jack"],
		"fav.movie": "Deer Hunter",
		"friends": [
			{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
			{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
			{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
		]
	}`)

	parser := jsonvx.NewParser(data, nil)

	node, err := parser.Parse()
	if err != nil {
		panic(fmt.Sprintf("failed to parse JSON: %s", err))
	}

	rootObj, ok := jsonvx.AsObject(node)
	if !ok {
		panic("expected root node to be an object")
	}

	ageNode, err := rootObj.QueryPath("age")
	if err != nil {
		panic(fmt.Sprintf("failed to query 'age' field: %s", err))
	}

	ageNum, ok := jsonvx.AsNumber(ageNode)
	if !ok {
		panic("expected 'age' to be a number")
	}

	ageValue, err := ageNum.Value()
	if err != nil {
		panic(fmt.Sprintf("failed to convert 'age' to numeric value: %s", err))
	}

	fmt.Println(ageValue) // 37
}

Query Path Syntax

Access deeply nested fields in your parsed JSON array or object structure using the QueryPath method, which accepts a variadic list of strings to represent the path segments.

Using the json data above, we can query for specific values using the QueryPath method:

// Get first name
strNode, _ := rootObj.QueryPath("name", "first") // => "Tom"

// get children array
arrayNode, _ := rootObj.QueryPath("children") // => ["Sara", "Alex", "Jack"]

// Get second child
strNode, _ = rootObj.QueryPath("children", "1") // => "Alex"

// Get favorite movie (with dot in key name)
strNode, _ = rootObj.QueryPath("fav.movie") // => "Deer Hunter"

// Get first friend object
objNode, _ := rootObj.QueryPath("friends", "0") // => {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]}

// Get last name of first friend
strNode, _ = rootObj.QueryPath("friends", "0", "last") // => "Murphy"

// Get second social network of second friend
strNode, _ = rootObj.QueryPath("friends", "1", "nets", "1") // => "tw"

// Get age of third friend
numNode, _ := rootObj.QueryPath("friends", "2", "age") // => 47

Configuring The Parser

You can configure the Parser using the functional options pattern, allowing you to enable relaxed JSON features individually. By default, the parser is strict (all options disabled), matching the ECMA-404 specification. To allow non-standard or user-friendly formats (like JSON5), pass options when creating the config:

AllowExtraWS:

Allows extra whitespace characters that are not normally permitted by strict JSON.

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowExtraWS(true))
parser := jsonvx.NewParser([]byte("{\"key\":\v\"value\"}"), cfg) // valid Vertical Tab
parser := jsonvx.NewParser([]byte("{\"key\":\f\"value\"}"), cfg) // valid Form Feed
parser := jsonvx.NewParser([]byte("{\"key\":\u0085\"value\"}"), cfg) // valid Next Line
parser := jsonvx.NewParser([]byte("{\"key\":\u00A0\"value\"}"), cfg) // valid No-Break Space
AllowHexNumbers:

Enables support for hexadecimal numeric literals (e.g., 0x1F).

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowHexNumbers(true))
parser := jsonvx.NewParser([]byte("0x1F"), cfg) // valid 31 in hex
AllowPointEdgeNumbers:

Allows numbers like .5 or 5. without requiring a digit before/after the decimal point.

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowPointEdgeNumbers(true))
parser := jsonvx.NewParser([]byte(".5"), cfg) // valid pre decimal point number
parser := jsonvx.NewParser([]byte("5."), cfg) // valid post decimal point number
AllowInfinity:

Enables the use of Infinity, -Infinity and +Infinity as number values.

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowInfinity(true))
parser := jsonvx.NewParser([]byte("Infinity"), cfg) // valid positive infinity
parser := jsonvx.NewParser([]byte("-Infinity"), cfg) // valid negative infinity
parser := jsonvx.NewParser([]byte("+Infinity"), cfg) // valid only if AllowLeadingPlus is enabled
AllowNaN:

Allows NaN (Not-a-Number) as a numeric value.

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowNaN(true))
parser := jsonvx.NewParser([]byte("NaN"), cfg) // valid NaN
parser := jsonvx.NewParser([]byte("-NaN"), cfg) // valid NaN
parser := jsonvx.NewParser([]byte("+NaN"), cfg) // valid NaN only if AllowLeadingPlus is enabled
AllowLeadingPlus:

Permits a leading '+' in numbers (e.g., +42).

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowLeadingPlus(true))
parser := jsonvx.NewParser([]byte("+99"), cfg) // valid positive number
AllowUnquoted:

Enables parsing of unquoted object keys (e.g., {foo: "bar"})

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowUnquoted(true))
parser := jsonvx.NewParser([]byte(`{foo: "bar"}`), cfg) // valid only for unquoted keys and not for unquoted values
AllowSingleQuotes:

Allows strings to be enclosed in single quotes (' ') in addition to double quotes.

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowSingleQuotes(true))
parser := jsonvx.NewParser([]byte(`{'name': 'Tom'}`), cfg) // valid single-quoted string
AllowNewlineInStrings:

Permits multiple new line characters (\n) being escaped.

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowNewlineInStrings(true))
parser := jsonvx.NewParser([]byte(`"hello \
 world"`), cfg) // valid escaped new line
AllowOtherEscapeChars:

Enables support for escape sequences other than \\, \/, \b, \n, \f, \r, \t and Unicode escapes (\uXXXX).

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowOtherEscapeChars(true))
parser := jsonvx.NewParser([]byte(`"hello\qworld"`), cfg) // valid other escape character
AllowTrailingCommaArray:

Permits a trailing comma in array literals (e.g., [1, 2, ]).

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowTrailingCommaArray(true))
parser := jsonvx.NewParser([]byte(`[1, 2, 3, ]`), cfg) // valid array with trailing comma
AllowTrailingCommaObject:

Permits a trailing comma in object literals (e.g., {"a": 1,}).

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowTrailingCommaObject(true))
parser := jsonvx.NewParser([]byte(`{"a": 1,}`), cfg) // valid object with trailing comma
AllowLineComments:

Enables the use of single-line comments (// ...).

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowLineComments(true))
parser := jsonvx.NewParser([]byte(`// comment
123`), cfg) // valid number after liner comment
AllowBlockComments:

Enables the use of block comments (/_ ... _/).

cfg := jsonvx.NewParserConfig(jsonvx.WithAllowBlockComments(true))
parser := jsonvx.NewParser([]byte(`/* comment */ 123`), cfg)
AllowJSON5:

Enables the use of JSON5 syntax.

parser := jsonvx.NewParser([]byte(`
{
// comments
unquoted: 'and you can quote me on that',
singleQuotes: 'I can use "double quotes" here',
lineBreaks: "Look, Mom! \
No \\n's!",
hexadecimal: 0xdecaf,
leadingDecimalPoint: .8675309, andTrailing: 8675309.,
positiveSign: +1,
trailingComma: 'in objects', andIn: ['arrays',],
"backwardsCompatible": "with JSON",
}
`), jsonvx.JSON5Config())

Parsing behavior

Below are examples of how to parse, traverse and retrieve values from the parsed JSON input using the Parser.

Object
  • Objects are stored as a slice of jsonvx.KeyValue struct.
  • keys are stored as []byte and sorted lexicographically for log(n) value retrieval.
  • values are stored as jsonvx.JSON
  • Each key-value pair is accessible using the ForEach method.
  • Mixed value types (e.g., numbers, strings, objects) are obviously supported.
  • Duplicate keys are included, but the first key-value pair is gotten with the QueryPath method.

This example shows how to parse a JSON object using jsonvx, cast it to an jsonvx.Object node, and iterate over key-value pairs using the built-in ForEach method.

parser := jsonvx.NewParser([]byte(`{"name": "Alice", "age": 30}`), jsonvx.NewParserConfig())

// Parse the JSON input
node, err := parser.Parse()
if err != nil {
	panic(fmt.Sprintf("failed to parse JSON: %s", err))
}

// Cast the parsed node to an ObjectNode
objNode, ok := jsonvx.AsObject(node)
if !ok {
	panic("expected root node to be an object")
}

// Iterate over key-value pairs using ForEach
objNode.ForEach(func(key []byte, value jsonvx.JSON, object *jsonvx.Object) {
	fmt.Printf("Key: %s, Value: %v\n", string(key), value)
})
Array
  • Items are stored as a slice of jsonvx.JSON
  • Each item is accessible using the ForEach method.

This example demonstrates how to parse a JSON array using jsonvx, cast it to an jsonvx.Array node, and iterate over its elements using the built-in ForEach method.

parser := jsonvx.NewParser([]byte(`[1, 2, 3]`), jsonvx.NewParserConfig())

// Parse the JSON input
node, err := parser.Parse()
if err != nil {
	panic(fmt.Sprintf("failed to parse JSON: %s", err))
}

// Cast the parsed node to an ArrayNode
arrNode, ok := jsonvx.AsArray(node)
if !ok {
	panic("expected root node to be an array")
}

// Iterate over each item using ForEach
arrNode.ForEach(func(item jsonvx.JSON, index int, array *jsonvx.Array) {
	fmt.Printf("Item %d: %v\n", index, item)
})
String
  • JSON string values are parsed as jsonvx.String.
  • Value() returns the raw Go` string value.

This example demonstrates how to parse a JSON string using jsonvx, cast it to an jsonvx.String node, and get its string value using the built-in Value method.

parser := jsonvx.NewParser([]byte(`"Hello, World!"`), jsonvx.NewParserConfig())

// Parse the JSON input
node, err := parser.Parse()
if err != nil {
	panic(fmt.Sprintf("failed to parse JSON: %s", err))
}

// Cast the parsed node to a StringNode
strNode, ok := jsonvx.AsString(node)
if !ok {
	panic("expected root node to be a string")
}

// Extract the underlying Go string value
strValue, err := strNode.Value()
if err != nil {
	panic(fmt.Sprintf("failed to extract string value: %s", err))
}

fmt.Println(strValue) // Output: Hello, World!
Number
  • JSON numbers are parsed as a jsonvx.Number.
  • Value() returns the raw Go float64 value.
  • Integer, Float, SciNot, Hex, Infinity and ironically NaN number types are supported.

This example demonstrates how to parse a JSON number using jsonvx, cast it to an jsonvx.Number node, and get float64 its value using the built-in Value method.

parser := jsonvx.NewParser([]byte("123456"), jsonvx.NewParserConfig())

// Parse the JSON input
node, err := parser.Parse()
if err != nil {
	panic(fmt.Sprintf("failed to parse JSON: %s", err))
}

// Cast the parsed node to a NumberNode
numNode, ok := jsonvx.AsNumber(node)
if !ok {
	panic("expected root node to be a number")
}

// Extract the underlying Go float64 value
numValue, err := numNode.Value()
if err != nil {
	panic(fmt.Sprintf("failed to extract number value: %s", err))
}

fmt.Println(numValue) // Output: 123456
Boolean
  • JSON booleans are parsed as a jsonvx.Boolean.
  • Value() returns the raw Go bool value.

This example demonstrates how to parse a JSON boolean using jsonvx, cast it to an jsonvx.Boolean node, and get bool its value using the built-in Value method.

parser := jsonvx.NewParser([]byte("true"), jsonvx.NewParserConfig())

// Parse the JSON input
node, err := parser.Parse()
if err != nil {
	panic(fmt.Sprintf("failed to parse JSON: %s", err))
}

// Cast the parsed node to a BooleanNode
boolNode, ok := jsonvx.AsBoolean(node)
if !ok {
	panic("expected root node to be a boolean")
}

// Extract the underlying Go value
trueValue, err := boolNode.Value()
if err != nil {
	panic(fmt.Sprintf("failed to extract boolean value: %s", err))
}

fmt.Println(trueValue) // Output: true
Null
  • JSON null values are parsed as a jsonvx.Null.
  • Value() returns the raw Go nil value.

This example demonstrates how to parse a JSON null using jsonvx, cast it to an jsonvx.Null node, and get nil its value using the built-in Value method.

parser := jsonvx.NewParser([]byte("null"), jsonvx.NewParserConfig())

// Parse the JSON input
node, err := parser.Parse()
if err != nil {
	panic("failed to parse JSON: %s", err)
}

// Cast the parsed node to a NullNode
nullNode, ok := jsonvx.AsNull(node)
if !ok {
  panic("expected root node to be null")
}

// Extract the underlying Go value
nilValue, _ := nullNode.Value()
fmt.Println(nilValue) // Output: <nil>
Comments
  • Comments are ignored during parsing.
  • A JSON input with only comments and no data will result in a parse error.
parser := jsonvx.NewParser([]byte("/* Block Comment */"), jsonvx.NewParserConfig(
	jsonvx.WithAllowBlockComments(true), jsonvx.WithAllowLineComments(true),
))

// parse the JSON
node, err := parser.Parse()
if err != nil {
	panic(fmt.Sprintf("failed to parse JSON: %s", err))
}

Maintainers

  • bube054 - Attah Gbubemi David (author)

Other helpful projects

License

This project is licensed under the MIT. See the LICENSE file for details.

Documentation

Overview

Package jsonvx is a highly configurable JSON parser, querier, and formatter for Go.

It supports both strict JSON (as defined by ECMA-404) and up to a more relaxed variant such as JSON5. This makes it ideal for parsing user-generated data, configuration files, or legacy formats that don't fully comply with the JSON specification.

With a single ParserConfig struct, jsonvx gives you fine-grained control over how JSON is parsed. You can enable or disable features like:

  • Hexadecimal numbers (0xFF)
  • NaN and Infinity as numeric values
  • Leading plus signs in numbers (+42)
  • Decimal edge cases like .5 or 5.
  • Unquoted object keys ({key: "value"})
  • Single-quoted strings ('text')
  • Newlines inside strings
  • Escape characters outside the standard set
  • Trailing commas in arrays or objects
  • Line comments (// comment) and Block comments (/* comment */)
  • Extra whitespace in unusual places
  • Enable JSON5

After parsing, jsonvx gives you a clean abstract syntax tree (AST) that you can either traverse manually or query using the built-in API. Each node in the tree implements a common JSON interface, so you can safely inspect, transform, or stringify data as needed.

jsonvx is designed for flexibility and correctness — not raw performance. It prioritizes clarity and configurability over speed, making it perfect for tools, linters, formatters, and config loaders where input may vary or include non-standard extensions.

If you need full control over how JSON is interpreted and a structured way to work with the result, jsonvx is for you.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotString  = errors.New("value is not a JSON string")
	ErrNotNumber  = errors.New("value is not a JSON number")
	ErrNotBoolean = errors.New("value is not a JSON boolean")
	ErrNotNull    = errors.New("value is not null")

	ErrInvalidQueryKey   = errors.New("invalid query key")
	ErrExpectedIndex     = errors.New("invalid query key, expected integer index")
	ErrIndexOutOfRange   = errors.New("index out of range")
	ErrEmptyArray        = errors.New("array is empty")
	ErrInvalidJSONType   = errors.New("invalid JSON type")
	ErrQueryExceedsDepth = errors.New("query exceeds depth for scalar value")
)

Common errors for type assertion and query path resolution.

View Source
var (
	ErrJSONSyntax          = errors.New("JSON syntax error")
	ErrJSONUnexpectedChar  = errors.New("unexpected character in JSON input")
	ErrJSONNoContent       = errors.New("no meaningful content to parse")
	ErrJSONMultipleContent = errors.New("multiple JSON values")
)
View Source
var (
	ErrIllegalToken             = errors.New("illegal token encountered")
	ErrUnexpectedToken          = errors.New("unexpected token encountered")
	ErrUnbalancedArrayBrackets  = errors.New("unbalanced brackets in array")
	ErrUnbalancedObjectBrackets = errors.New("unbalanced brackets in object")
)

Functions

func ToFloat

func ToFloat(input []byte) (float64, error)

func ToInt

func ToInt(input []byte) (int64, error)

func WithAllowBlockComments

func WithAllowBlockComments(allow bool) func(*ParserConfig)

func WithAllowExtraWS

func WithAllowExtraWS(allow bool) func(*ParserConfig)

WithAllowExtraWS is the functional option setters for the AllowExtraWS flag.

func WithAllowHexNumbers

func WithAllowHexNumbers(allow bool) func(*ParserConfig)

Functional option setters for the AllowHexNumbers flag.

func WithAllowInfinity

func WithAllowInfinity(allow bool) func(*ParserConfig)

func WithAllowLeadingPlus

func WithAllowLeadingPlus(allow bool) func(*ParserConfig)

func WithAllowLineComments

func WithAllowLineComments(allow bool) func(*ParserConfig)

func WithAllowNaN

func WithAllowNaN(allow bool) func(*ParserConfig)

func WithAllowNewlineInStrings

func WithAllowNewlineInStrings(allow bool) func(*ParserConfig)

func WithAllowOtherEscapeChars

func WithAllowOtherEscapeChars(allow bool) func(*ParserConfig)

func WithAllowPointEdgeNumbers

func WithAllowPointEdgeNumbers(allow bool) func(*ParserConfig)

Functional option setters for the AllowHexNumbers flag.

func WithAllowSingleQuotes

func WithAllowSingleQuotes(allow bool) func(*ParserConfig)

func WithAllowTrailingCommaArray

func WithAllowTrailingCommaArray(allow bool) func(*ParserConfig)

func WithAllowTrailingCommaObject

func WithAllowTrailingCommaObject(allow bool) func(*ParserConfig)

func WithAllowUnquoted

func WithAllowUnquoted(allow bool) func(*ParserConfig)

func WrapJSONMultipleContentError

func WrapJSONMultipleContentError(token Token) error

func WrapJSONSyntaxError

func WrapJSONSyntaxError(token Token) error

func WrapJSONUnexpectedCharError

func WrapJSONUnexpectedCharError(token Token) error

func WrapUnexpectedCharError

func WrapUnexpectedCharError(baseErr error, token Token) error

Types

type Array

type Array struct {
	Items []JSON
}

Array represents a JSON array.

func AsArray

func AsArray(j JSON) (*Array, bool)

AsArray safely casts a JSON to a *Array.

func (*Array) Equal

func (a *Array) Equal(a2 JSON) bool

func (*Array) ForEach

func (a *Array) ForEach(cb ArrayCallback)

ForEach calls the given callback for each item in the array. It provides the item, its index, and the array itself.

func (*Array) Len

func (a *Array) Len() int

func (*Array) QueryPath

func (a *Array) QueryPath(paths ...string) (JSON, error)

QueryPath retrieves a nested item using a slice of string indices.

func (*Array) String

func (a *Array) String() string

type ArrayCallback

type ArrayCallback func(item JSON, index int, array *Array)

ArrayCallback defines the function signature for iterating over items in a JSON array. - item: the current element - index: the index of the element - array: the array being iterated

type Boolean

type Boolean struct {
	Token *Token
}

Boolean represents a JSON boolean (true or false).

func AsBoolean

func AsBoolean(j JSON) (*Boolean, bool)

AsBoolean safely casts a JSON to a *Boolean.

func (*Boolean) Equal

func (b *Boolean) Equal(b2 JSON) bool

func (*Boolean) String

func (b *Boolean) String() string

func (*Boolean) Value

func (b *Boolean) Value() (bool, error)

Value returns the boolean value or an error if the token is invalid.

type JSON

type JSON interface {
	fmt.Stringer
	Equal(JSON) bool
}

JSON is a common interface implemented by all JSON types (Null, Boolean, etc.).

type KeyValue

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

KeyValue represents a key-value pair in a JSON object.

func (*KeyValue) Equal

func (kv *KeyValue) Equal(kv2 *KeyValue) bool

type Lexer

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

Lexer performs lexical analysis on a JSON-like input stream. It breaks the raw input into a sequence of tokens according to the parsing rules defined in the provided ParserConfig.

The Lexer operates on raw byte slices for performance, and tracks position and line information to support error reporting and debugging.

func NewLexer

func NewLexer(input []byte, cfg *ParserConfig) *Lexer

NewLexer creates a new Lexer instance using the given input and configuration.

It immediately reads the first character to initialize internal state, so the lexer is ready for tokenization right after creation.

func (*Lexer) String

func (l *Lexer) String() string

String returns a human-readable representation of the current state of the Lexer. It includes the input, current line number, character position, read position, and the current character.

func (*Lexer) Token

func (l *Lexer) Token() Token

Token returns the current token being parsed by the lexer.

func (*Lexer) Tokens

func (l *Lexer) Tokens() Tokens

Tokens returns a slice of all tokens produced so far by the lexer.

func (*Lexer) TokensWithout

func (l *Lexer) TokensWithout(kind TokenKind) Tokens

TokensWithoutWhitespace returns a slice of all tokens without whitespace produced so far by the lexer.

type Null

type Null struct {
	Token *Token
}

Null represents a JSON null value.

func AsNull

func AsNull(j JSON) (*Null, bool)

AsNull safely casts a JSON to a *Null.

func (*Null) Equal

func (n *Null) Equal(n2 JSON) bool

func (*Null) String

func (n *Null) String() string

func (*Null) Value

func (n *Null) Value() (any, error)

Value returns nil if the token is valid, or an error otherwise.

type Number

type Number struct {
	Token *Token
}

Number represents a JSON number (integer, float, hex, etc.).

func AsNumber

func AsNumber(j JSON) (*Number, bool)

AsNumber safely casts a JSON to a *Number.

func (*Number) Equal

func (n *Number) Equal(n2 JSON) bool

func (*Number) String

func (n *Number) String() string

func (*Number) Value

func (n *Number) Value() (float64, error)

Value attempts to parse the number as float64, depending on its subtype.

type Object

type Object struct {
	Properties []KeyValue
}

Object represents a JSON object.

func AsObject

func AsObject(j JSON) (*Object, bool)

AsObject safely casts a JSON to a *Object.

func (*Object) Equal

func (o *Object) Equal(o2 JSON) bool

func (*Object) ForEach

func (o *Object) ForEach(cb ObjectCallback)

ForEach calls the given callback for each key-value pair in the object. It provides the key, value, and the object itself.

func (*Object) Len

func (o *Object) Len() int

func (*Object) QueryPath

func (o *Object) QueryPath(paths ...string) (JSON, error)

QueryPath retrieves a nested value via key-based path traversal.

func (*Object) String

func (o *Object) String() string

type ObjectCallback

type ObjectCallback func(key []byte, value JSON, object *Object)

ObjectCallback defines the function signature for iterating over properties in a JSON object. - key: the property's key as a byte slice - value: the property's value - object: the object being iterated

type Parser

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

func NewParser

func NewParser(input []byte, config *ParserConfig) Parser

func (*Parser) Parse

func (p *Parser) Parse() (JSON, error)

type ParserConfig

type ParserConfig struct {
	AllowExtraWS bool // AllowExtraWS allows extra whitespace characters that are not normally permitted by strict JSON.

	AllowHexNumbers       bool // AllowHexNumbers enables support for hexadecimal numeric literals (e.g., 0xFF).
	AllowPointEdgeNumbers bool // AllowPointEdgeNumbers allows numbers like `.5` or `5.` without requiring a digit before/after the decimal point.

	AllowInfinity    bool // AllowInfinity enables the use of `Infinity` and `-Infinity` as number values.
	AllowNaN         bool // AllowNaN allows `NaN` (Not-a-Number) as a numeric value.
	AllowLeadingPlus bool // AllowLeadingPlus permits a leading '+' in numbers (e.g., `+42`).

	AllowUnquoted         bool // AllowUnquoted enables parsing of unquoted object keys (e.g., `{foo: "bar"}`).
	AllowSingleQuotes     bool // AllowSingleQuotes allows strings to be enclosed in single quotes (' ') in addition to double quotes.
	AllowNewlineInStrings bool // AllowNewlineInStrings permits multiple new line characters being escaped.
	AllowOtherEscapeChars bool // AllowOtherEscapeChars enables support for escape sequences other than \\, \/, \b, \n, \f, \r, \t and Unicode escapes (\uXXXX).

	AllowTrailingCommaArray  bool // AllowTrailingCommaArray permits a trailing comma in array literals (e.g., `[1, 2, ]`).
	AllowTrailingCommaObject bool // AllowTrailingCommaObject permits a trailing comma in object literals (e.g., `{"a": 1,}`).

	AllowLineComments  bool // AllowLineComments enables the use of single-line comments (// ...).
	AllowBlockComments bool // AllowBlockComments enables the use of block comments (/* ... */).
}

ParserConfig defines the encoding and decoding behavior for the JSON parser.

By default, all fields are false (strict mode). Enabling individual fields allows the parser to accept features that are not allowed by the standard ECMA-404 specification but may appear in relaxed formats like JSON5 or user-generated JSON.

func JSON5Config

func JSON5Config() *ParserConfig

JSON5Config returns a ParserConfig with all features enabled for JSON5 compatibility.

func NewParserConfig

func NewParserConfig(opts ...func(*ParserConfig)) *ParserConfig

NewParserConfig creates a new ParserConfig instance, optionally applying one or more configuration options. Options are applied in the order provided.

func (*ParserConfig) String

func (c *ParserConfig) String() string

String returns a formatted string representing all configuration options in the ParserConfig. Each field is listed with its corresponding boolean value.

type String

type String struct {
	Token *Token
}

String represents a JSON string.

func AsString

func AsString(j JSON) (*String, bool)

AsString safely casts a JSON to a *String.

func (*String) Equal

func (s *String) Equal(s2 JSON) bool

func (*String) String

func (s *String) String() string

func (*String) Value

func (s *String) Value() (string, error)

Value returns the string or an error if invalid.

type Token

type Token struct {
	Kind    TokenKind    // The general kind of the token (e.g., STRING, NUMBER).
	SubKind TokenSubKind // The specific sub kind within a kind (e.g., INTEGER vs FLOAT).
	Literal []byte       // The literal value of the token.
	Line    int          // The line number where the token appears (1-based index).
	Column  int          // The column position in the line (0-based index).
}

Token represents a single lexical token, including its kind, value, and position.

func (*Token) Equal

func (t *Token) Equal(t2 *Token) bool

func (*Token) String

func (t *Token) String() string

String returns a human-readable representation of the token.

func (*Token) Value

func (t *Token) Value() any

type TokenKind

type TokenKind int

TokenKind represents the kind of a token, used during both lexical analysis and by tools that query parsed node structures.

const (
	EOF                TokenKind = iota // EOF indicates the end of input.
	ILLEGAL                             // ILLEGAL indicates an unrecognized or invalid token.
	WHITESPACE                          // WHITESPACE represents any space character.
	COMMENT                             // COMMENT represents a comment
	STRING                              // STRING represents a string literal.
	NUMBER                              // NUMBER represents any numeric literal.
	NULL                                // NULL represents a null value.
	BOOLEAN                             // BOOLEAN represents a boolean value.
	COMMA                               // COMMA represents a ',' separator.
	COLON                               // COLON represents a ':' separator.
	LEFT_SQUARE_BRACE                   // LEFT_SQUARE_BRACE represents '['.
	RIGHT_SQUARE_BRACE                  // RIGHT_SQUARE_BRACE represents ']'.
	LEFT_CURLY_BRACE                    // LEFT_CURLY_BRACE represents '{'.
	RIGHT_CURLY_BRACE                   // RIGHT_CURLY_BRACE represents '}'.
)

func (TokenKind) String

func (t TokenKind) String() string

String returns a string representation of the TokenKind.

type TokenSubKind

type TokenSubKind int

TokenSubKind represents the subtype of a token, such as numeric format or identifier type.

const (
	NONE TokenSubKind = iota // NONE represents the absence of a sub kind.

	FALSE // FALSE represents a boolean false.
	TRUE  // TRUE represents a boolean true.

	SINGLE_QUOTED // SINGLE_QUOTED represents a single quoted string value.
	DOUBLE_QUOTED // DOUBLE_QUOTED represents a double quoted string value.
	IDENT         // IDENT represents an unquoted identifier.

	INTEGER // INTEGER represents an integer (positive or negative).
	FLOAT   // FLOAT represents a floating-point number (positive or negative).
	SCI_NOT // SCI_NOT represents scientific notation (e.g., 1e10).
	HEX     // HEX represents a hexadecimal number (e.g., 0xFF).
	INF     // INF represents an Infinity literal (positive or negative).
	NaN     // NaN represents a Not-a-Number literal.

	LINE_COMMENT  // LINE_COMMENT represents a single-line comment (// ...).
	BLOCK_COMMENT // BLOCK_COMMENT represents a block comment (/* ... */).

	INVALID_CHARACTER      // INVALID_CHARACTER represents an invalid or unexpected character.
	INVALID_WHITESPACE     // INVALID_WHITESPACE represents an invalid or misplaced whitespace.
	INVALID_NULL           // INVALID_NULL represents an invalid 'null' literal.
	INVALID_TRUE           // INVALID_TRUE represents an invalid 'true' literal.
	INVALID_FALSE          // INVALID_FALSE represents an invalid 'false' literal.
	INVALID_COMMENT        // INVALID_COMMENT represents an improperly formed comment.
	INVALID_LINE_COMMENT   // INVALID_LINE_COMMENT represents a malformed single-line comment.
	INVALID_BLOCK_COMMENT  // INVALID_BLOCK_COMMENT represents a malformed block comment.
	INVALID_STRING         // INVALID_STRING represents a malformed or unterminated string.
	INVALID_HEX_STRING     // INVALID_HEX_STRING represents an invalid hexadecimal string.
	INVALID_NEWLINE_STRING // INVALID_NEWLINE_STRING represents a string that contains an invalid newline.
	INVALID_ESCAPED_STRING // INVALID_ESCAPED_STRING represents a string with an invalid escape sequence.
	INVALID_LEADING_ZERO   // INVALID_LEADING_ZERO represents a number with an invalid leading zero.
	INVALID_LEADING_PLUS   // INVALID_LEADING_PLUS represents a number with an invalid leading plus sign.
	INVALID_NaN            // INVALID_NaN represents a malformed NaN literal.
	INVALID_INF            // INVALID_INF represents a malformed Infinity literal.
	INVALID_POINT_EDGE_DOT // INVALID_POINT_EDGE_DOT represents a number with a misplaced or standalone dot.
	INVALID_HEX_NUMBER     // INVALID_HEX_NUMBER represents a malformed hexadecimal number.
)

func (TokenSubKind) String

func (t TokenSubKind) String() string

String returns a string representation of the TokenSubKind.

type Tokens

type Tokens []Token

Tokens is a slice of Token.

func (Tokens) Equal

func (tks Tokens) Equal(tks2 Tokens) bool

func (Tokens) Split

func (tks Tokens) Split() ([][2]int, error)

func (Tokens) String

func (tks Tokens) String() string

String returns a formatted string listing all tokens in the slice.

Jump to

Keyboard shortcuts

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