Help us shape the future of Go! Take the 2026 Go Developer Survey

jseq

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Aug 29, 2026 License: MIT Imports: 9 Imported by: 0

README

Jseq - streaming JSON parser

Go Reference Tests Coverage Status

This is jseq, a streaming JSON parser.

The main function in this package, Values, produces JSON values from its input as soon as they are encountered. This means that interior values − those nested inside a JSON object or array − are produced first, before the surrounding structure is complete.

Each value produced by Values is paired with an RFC 6901-style JSON “pointer” that can locate it within its top-level object.

For a concrete example, consider this JSON input:

{"hello": [1, 2], "world": [3, 4]}

Given this input, Values produces pointer/value pairs in this order:

Pointer Value
"/hello/0" 1
"/hello/1" 2
"/hello" [1, 2]
"/world/0" 3
"/world/1 4
"/world" [3, 4]
"" {"hello": [1, 2], "world": [3, 4]}

For more information, see the Go doc for this package.

Usage

If r is the source of some JSON-encoded data, then typical usage looks like this:

tokens, errptr1 := jseq.Tokens(r)
pairs, errptr2 := jseq.Values(tokens)

for pointer, value := range pairs {
  // Handle a value.
  // Note that you can use len(pointer)==0
  // to detect when you’ve parsed a complete top-level object.
  // (More generally, len(pointer) tells you the nesting depth of the value.)
}
if err := *errptr1; err != nil {
  // Handle error from jseq.Tokens
}
if err := *errptr2; err != nil {
  // Handle error from jseq.Values
}

Documentation

Overview

Package jseq supplies streaming parsers for JSON tokens and values.

Example
package main

import (
	"errors"
	"fmt"
	"strings"

	"github.com/bobg/jseq"
)

func main() {
	r := strings.NewReader(`{"hello": [1, 2]} {"world": [3, 4]}`)
	tokens, errptr1 := jseq.Tokens(r)
	values, errptr2 := jseq.Values(tokens)
	for pointer, value := range values {
		fmt.Printf("%q: %v\n", pointer.Text(), value)
	}
	if err := errors.Join(*errptr1, *errptr2); err != nil {
		panic(err)
	}
}
Output:

"/hello/0": 1
"/hello/1": 2
"/hello": [1 2]
"": map[hello:[1 2]]
"/world/0": 3
"/world/1": 4
"/world": [3 4]
"": map[world:[3 4]]

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnexpectedCloseBrace is returned when a close brace ("}") is encountered but there is no object on the stack.
	ErrUnexpectedCloseBrace = errors.New("unexpected close brace: stack empty")

	// ErrUnexpectedCloseBracket is returned when a close bracket ("]") is encountered but there is no array on the stack.
	ErrUnexpectedCloseBracket = errors.New("unexpected close bracket: stack empty")
)

Functions

func Tokens

func Tokens(r io.Reader, opts ...jsontext.Options) (iter.Seq[jsontext.Token], *error)

Tokens parses JSON tokens from r and returns them as an iter.Seq. This sequence is suitable as input to Values.

After consuming the resulting sequence, the caller may check for errors by dereferencing the returned error pointer.

func Values

func Values(tokens iter.Seq[jsontext.Token]) (iter.Seq2[Pointer, any], *error)

Values consumes a sequence of JSON tokens and produces a sequence of JSON values, each paired with the Pointer that can locate it within its top-level object.

The input to this function may be supplied by a call to Tokens.

Values are produced as they are encountered, in depth-first fashion, making this a "streaming" or "event-based" parser. For example, given a sequence of tokens representing this input:

{"hello": [1, 2], "world": [3, 4]}

Values will produce pointer/value pairs in this order:

"/hello/0"  1
"/hello/1"  2
"/hello"    [1, 2]
"/world/0"  3
"/world/1"  4
"/world"    [3, 4]
""          {"hello": [1, 2], "world": [3, 4]}

Note that object keys are not considered values to be separately emitted.

Value types in the resulting sequence are:

  • []any for arrays
  • map[string]any for objects
  • strings for strings
  • boolean for booleans
  • Null for null
  • Number for numbers

The input may contain multiple top-level JSON values, each of which will be paired with an empty Pointer. If the input ends in the middle of a JSON value, Values produces an io.ErrUnexpectedEOF error.

After consuming the resulting sequence, the caller may check for errors by dereferencing the returned error pointer.

Types

type BadPointerElementError added in v0.5.0

type BadPointerElementError struct {
	Val any
}

BadPointerElementError is returned when a JSON pointer element is of an unexpected type (neither string nor int).

func (BadPointerElementError) Error added in v0.5.0

func (e BadPointerElementError) Error() string

type BoundsError added in v0.5.0

type BoundsError struct {
	Index int
}

BoundsError is returned when a JSON array index is out of bounds.

func (BoundsError) Error added in v0.5.0

func (e BoundsError) Error() string

type NonArrayError added in v0.5.0

type NonArrayError struct {
	Val   any
	Index int
}

NonArrayError is returned when a JSON array is expected but a non-array value is encountered.

func (NonArrayError) Error added in v0.5.0

func (e NonArrayError) Error() string

type NonObjectError added in v0.5.0

type NonObjectError struct {
	Val any
	Key string
}

NonObjectError is returned when a JSON object is expected but a non-object value is encountered.

func (NonObjectError) Error added in v0.5.0

func (e NonObjectError) Error() string

type Null

type Null struct{}

Null is the type of a JSON "null" value.

type Number

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

Number is the type of a JSON number.

func Float

func Float(n float64) Number

Float produces a new Number from a float64 value.

func Int

func Int(n int64) Number

Int produces a new Number from an int64 value.

func NewNumber

func NewNumber(tok jsontext.Token) (Number, error)

NewNumber produces a new Number from a jsontext.Token. The input must have jsontext.Kind '0' ("number").

func Uint

func Uint(n uint64) Number

Uint produces a new Number from a uint64 value.

func (Number) Float

func (n Number) Float() float64

Float returns the number’s float64 value.

func (Number) Int

func (n Number) Int() (int64, bool)

Int returns the number’s int64 value, if possible. The boolean result indicates whether n can accurately be represented as an int64.

func (Number) String

func (n Number) String() string

String returns the number’s raw JSON representation.

func (Number) Uint

func (n Number) Uint() (uint64, bool)

Uint returns the number’s uint64 value, if possible. The boolean result indicates whether n can accurately be represented as a uint64.

type Pointer

type Pointer []any

Pointer is the type of a JSON pointer produced by Values. A JSON pointer is an index into a JSON document that uniquely identifies a specific value the document contains. It’s represented as a slice of tokens, where each token is either a string (for an object key) or an int (for an array index).

A Pointer can be converted to a jsontext.Pointer via its Text method. There are two differences between a Pointer and a jsontext.Pointer:

  1. A Pointer can distinguish between an array index and an object key that happen to have the same string representation; a jsontext.Pointer cannot.
  2. A Pointer does not perform any escaping of special characters in object keys (as required by RFC 6901); a jsontext.Pointer does.

func (Pointer) Locate

func (p Pointer) Locate(val any) (any, error)

Locate locates the element within val represented by p.

func (Pointer) Text

func (p Pointer) Text() jsontext.Pointer

Text converts p to a jsontext.Pointer.

type UnexpectedTokenKindError added in v0.5.0

type UnexpectedTokenKindError struct {
	Got, Want jsontext.Kind
}

UnexpectedTokenKindError is returned when a JSON token of an unexpected kind is encountered.

func (UnexpectedTokenKindError) Error added in v0.5.0

func (e UnexpectedTokenKindError) Error() string

Jump to

Keyboard shortcuts

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