parser-go-json

module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Jul 29, 2026 License: Apache-2.0

README

parser-go-json

Parser for JSON in Go, which tries to not allocate any memory.

We can parse json without unmarshaling it into a Go struct using the Parser interface:

import "github.com/katydid/parser-go-json/json"

func main() {
	jsonString := `{"otherfield": 123, "myfield": "myvalue"}`
	jsonParser := json.NewParser()
	jsonParser.Init([]byte(jsonString))
	myvalue, err := GetMyField(jsonParser)
	if err != nil {
		panic(err)
	}
	println(myvalue)
}

We can then use the parser to decode only myfield and skip over other fields and return "myvalue":

import (
	"github.com/katydid/parser-go/cast"
	"github.com/katydid/parser-go/parse"
)


func GetMyField(p parse.Parser) (string, error) {
	hint, err := p.Next()
	if hint != parse.EnterHint {
		return "", errors.New("expected object")
	}
	if err != nil {
		return "", err
	}
	for {
		hint, err = p.Next()
		if err != nil {
			return "", err
		}
		if hint != parse.FieldHint {
			return "", errors.New("expected field")
		}
		kind, fieldName, err := p.Token()
		if err != nil {
			return "", err
		}
		if kind != parse.StringKind {
			return "", errors.New("expected string")
		}
		if cast.ToString(fieldName) == "myfield" {
			hint, err = p.Next()
			if err != nil {
				return "", err
			}
			if hint != parse.ValueHint {
				return "", errors.New("expected field")
			}
			kind, val, err := p.Token()
			if err != nil {
				return "", err
			}
			if kind != parse.StringKind {
				return "", errors.New("expected string")
			}
			return cast.ToString(val), nil
		} else {
			p.Skip()
		}
	}
}

Special Considerations

  • The parser uses a buffer pool, which will allocate memory until it is warmed up.
  • Buffers are reused and pooled. This means that the String and Bytes methods, returns a string and []byte respectively that should be copied if it is needed again before calling Next, Token or Skip.
  • Arrays are indexed, which means that ["a","b","c"] will be parsed into something that looks like an integer indexed map: {O: "a", 1: "b", 2: "c"}.

Thank you

Thanks to the following people for consulting on the project:

I still made all the bad design decisions, so don't blame them. They only made the project better than it would have been without their advice.

Directories

Path Synopsis
Package json contains the implementation of a JSON parser.
Package json contains the implementation of a JSON parser.
internal/fork/jsontext
jsontext is a package of tests that were originally copied from https://github.com/go-json-experiment/json/blob/master/jsontext/decode_test.go
jsontext is a package of tests that were originally copied from https://github.com/go-json-experiment/json/blob/master/jsontext/decode_test.go
internal/fork/strconv
strconv was originally copied from the Go standard library's strconv package, but with several modifications.
strconv was originally copied from the Go standard library's strconv package, but with several modifications.
internal/fork/unquote
unquote is a package that is a copy of unquoteBytes from https://golang.org/src/encoding/json/decode.go
unquote is a package that is a copy of unquoteBytes from https://golang.org/src/encoding/json/decode.go
tag

Jump to

Keyboard shortcuts

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