jsonbind

package
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package jsonbind provides generated, reflection-free JSON document codecs.

Index

Constants

View Source
const DefaultMaxJSONBodyBytes int64 = 1 << 20

DefaultMaxJSONBodyBytes is the default JSON document limit (1 MiB).

Variables

View Source
var ErrBodyTooLarge = errors.New("jsonbind: JSON body too large")

ErrBodyTooLarge reports that a JSON document exceeded its configured limit.

Functions

func AppendAny added in v0.4.0

func AppendAny(dst []byte, v any) []byte

AppendAny appends an arbitrary Go value produced by rest-field decoding. It covers the shapes Parser.Any yields plus the common scalar types; anything else is written as null rather than failing an otherwise valid response.

func AppendBool added in v0.4.0

func AppendBool(dst []byte, v bool) []byte

AppendBool appends a JSON boolean.

func AppendFloat added in v0.4.0

func AppendFloat(dst []byte, v float64) []byte

AppendFloat appends a JSON number using encoding/json's formatting: shortest round-trip, switching to exponent form outside [1e-6, 1e21) and trimming the exponent's leading zero.

func AppendInt added in v0.4.0

func AppendInt(dst []byte, v int64) []byte

AppendInt appends a JSON number.

func AppendRaw added in v0.4.0

func AppendRaw(dst []byte, raw []byte) []byte

AppendRaw appends an already-encoded JSON value, or null when it is empty.

func AppendString added in v0.4.0

func AppendString(dst []byte, s string) []byte

AppendString appends a JSON string literal. Like encoding/json's encoder it escapes <, > and & so the result is safe to embed in HTML, and U+2028/U+2029 so it stays valid JavaScript.

func AppendUint added in v0.4.0

func AppendUint(dst []byte, v uint64) []byte

AppendUint appends a JSON number.

func DecodeJSON

func DecodeJSON[T any](r io.Reader) (T, error)

DecodeJSON decodes one JSON value from r into T using a generated codec. It does not inspect HTTP headers or use reflection on T's fields.

func DecodeJSONAny added in v0.4.0

func DecodeJSONAny(raw []byte) (any, error)

DecodeJSONAny decodes any JSON value into the Go shapes encoding/json uses for an `any` destination.

func DecodeJSONBool

func DecodeJSONBool(raw []byte) (bool, error)

DecodeJSONBool decodes a JSON boolean.

func DecodeJSONBoolSlice

func DecodeJSONBoolSlice(raw []byte) ([]bool, error)

DecodeJSONBoolSlice decodes a JSON array of booleans.

func DecodeJSONFloat64

func DecodeJSONFloat64(raw []byte) (float64, error)

DecodeJSONFloat64 decodes a JSON number as float64.

func DecodeJSONFloat64Slice

func DecodeJSONFloat64Slice(raw []byte) ([]float64, error)

DecodeJSONFloat64Slice decodes a JSON array of floats.

func DecodeJSONHint added in v0.4.3

func DecodeJSONHint[T any](r io.Reader, limit, hint int64) (T, error)

DecodeJSONHint is DecodeJSONLimit with an expected document size. A caller that knows the length up front — an HTTP handler with a Content-Length, say — lets the whole body land in one allocation; see ReadLimitHint.

func DecodeJSONInt

func DecodeJSONInt(raw []byte) (int, error)

DecodeJSONInt decodes a JSON number as int.

func DecodeJSONInt64

func DecodeJSONInt64(raw []byte) (int64, error)

DecodeJSONInt64 decodes a JSON number as int64.

func DecodeJSONInt64Slice

func DecodeJSONInt64Slice(raw []byte) ([]int64, error)

DecodeJSONInt64Slice decodes a JSON array of int64s.

func DecodeJSONIntSlice

func DecodeJSONIntSlice(raw []byte) ([]int, error)

DecodeJSONIntSlice decodes a JSON array of ints.

func DecodeJSONLimit

func DecodeJSONLimit[T any](r io.Reader, limit int64) (T, error)

DecodeJSONLimit is DecodeJSON with a per-call byte limit. A non-positive limit uses MaxJSONBodyBytes.

func DecodeJSONMapStringBool added in v0.4.0

func DecodeJSONMapStringBool(raw []byte) (map[string]bool, error)

DecodeJSONMapStringBool decodes a JSON object of booleans.

func DecodeJSONMapStringFloat64 added in v0.4.0

func DecodeJSONMapStringFloat64(raw []byte) (map[string]float64, error)

DecodeJSONMapStringFloat64 decodes a JSON object of floats.

func DecodeJSONMapStringInt added in v0.4.0

func DecodeJSONMapStringInt(raw []byte) (map[string]int, error)

DecodeJSONMapStringInt decodes a JSON object of ints.

func DecodeJSONMapStringInt64 added in v0.4.0

func DecodeJSONMapStringInt64(raw []byte) (map[string]int64, error)

DecodeJSONMapStringInt64 decodes a JSON object of int64s.

func DecodeJSONMapStringString

func DecodeJSONMapStringString(raw []byte) (map[string]string, error)

DecodeJSONMapStringString decodes a JSON object of strings.

func DecodeJSONString

func DecodeJSONString(raw []byte) (string, error)

DecodeJSONString decodes a JSON string value.

func DecodeJSONStringSlice

func DecodeJSONStringSlice(raw []byte) ([]string, error)

DecodeJSONStringSlice decodes a JSON array of strings.

func EncodeJSON

func EncodeJSON[T any](w io.Writer, v T) error

EncodeJSON encodes v as compact JSON to w using a generated codec. It does not set HTTP headers or status.

func FieldError

func FieldError(field, message string, cause error) error

FieldError annotates a JSON decoding error with its document field.

func GetBuffer added in v0.4.0

func GetBuffer() *[]byte

GetBuffer borrows an encode buffer. Generated code returns it with PutBuffer once the bytes have been written out.

func IsBlank added in v0.4.0

func IsBlank(data []byte) bool

IsBlank reports whether data holds no JSON document at all. Generated decoders treat that as the zero value rather than a parse error, which is how an absent body and an empty config file have always behaved.

func MaxJSONBodyBytes

func MaxJSONBodyBytes() int64

MaxJSONBodyBytes returns the effective JSON document limit.

func ParseMap added in v0.4.3

func ParseMap[T any](p *Parser, field, message string, read func(*Parser) (T, error)) (map[string]T, error)

ParseMap decodes a JSON object field, reading each member value with read. A JSON null decodes as a nil map and an empty object as a non-nil empty one. Errors are annotated the same way as ParseSlice.

func ParseSlice added in v0.4.3

func ParseSlice[T any](p *Parser, field, message string, read func(*Parser) (T, error)) ([]T, error)

ParseSlice decodes a JSON array field, reading each element with read. A JSON null decodes as a nil slice and an empty array as a non-nil empty one. Structural errors are annotated with the field's document name; an element error is annotated with message, or passed through unchanged when message is empty so a nested decoder can report its own fields.

func PutBuffer added in v0.4.0

func PutBuffer(b *[]byte)

PutBuffer returns an encode buffer to the pool. Oversized buffers are dropped so one large document does not pin memory for the process lifetime.

func RawJSONArray

func RawJSONArray(raw []byte) ([][]byte, error)

RawJSONArray splits a JSON array into its raw elements. Elements alias raw.

func ReadLimit

func ReadLimit(r io.Reader, limit int64) ([]byte, error)

ReadLimit reads at most limit bytes from r.

func ReadLimitHint added in v0.4.0

func ReadLimitHint(r io.Reader, limit, hint int64) ([]byte, error)

ReadLimitHint is ReadLimit with an expected size. A caller that knows the length up front — an HTTP handler with a Content-Length, say — lets the whole body land in one allocation instead of the repeated grow-and-copy io.ReadAll performs. A wrong hint costs nothing but the usual growth.

func RegisterDecode

func RegisterDecode[T any](fn func([]byte) (T, error))

RegisterDecode registers a generated JSON document decoder for T.

func RegisterEncode

func RegisterEncode[T any](fn func(io.Writer, T) error)

RegisterEncode registers a generated compact JSON encoder for T.

func RestJSONAny

func RestJSONAny(body *Object, exclude []string) (map[string]any, error)

RestJSONAny returns JSON fields not named in exclude.

func RestJSONMember added in v0.4.3

func RestJSONMember(body *Object, i int, exclude []string) (name string, raw []byte, ok bool)

RestJSONMember returns body's i'th member unless its name is in exclude. Paired with Object.Len it lets generated code sweep rest fields in one pass over the document instead of a name lookup per member.

func RestJSONNames added in v0.4.0

func RestJSONNames(body *Object, exclude []string) []string

RestJSONNames returns the names of JSON fields not named in exclude.

A raw rest field is typed map[string]json.RawMessage in the caller's struct, and Go will not convert a map[string][]byte to it however identical the element layout is. Handing back names keeps encoding/json — and the reflection it drags into a TinyGo binary — out of this package: generated code fills its own map with the value copies.

func SetMaxJSONBodyBytes

func SetMaxJSONBodyBytes(n int64)

SetMaxJSONBodyBytes changes the process-wide JSON document limit.

func SortedKeys added in v0.4.0

func SortedKeys[V any](m map[string]V) []string

SortedKeys orders map keys so a map encodes deterministically, matching encoding/json's behaviour. Generated encoders call it for every map-typed field and for payload:"*" rest maps.

Types

type Error

type Error struct {
	Code    string
	Message string
	Field   string
	// contains filtered or unexported fields
}

Error describes a transport-neutral JSON mapping failure.

func AsError

func AsError(err error) (*Error, bool)

AsError finds a JSON Error without using reflection-dependent errors.As.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

type Object added in v0.4.0

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

Object is a JSON object split into its top-level members in one pass.

The binder needs random access to body fields because a value may also come from the query string or a form, and the winner depends on the field's tag rather than on document order. Object gives that access without the cost of a map: names and values are subslices of the source buffer, so splitting a document allocates one slice rather than a map plus a copy per member.

Values alias the buffer the Object was built from. Copy anything that has to outlive it.

func BytesJSONMap

func BytesJSONMap(data []byte) (*Object, error)

BytesJSONMap splits a complete JSON object document.

func EmptyObject added in v0.4.0

func EmptyObject() *Object

EmptyObject returns an object with no members, for an absent or blank body.

func ParseObject added in v0.4.0

func ParseObject(data []byte) (*Object, error)

ParseObject splits a JSON object document into its members.

func RawJSONMap

func RawJSONMap(raw []byte) (*Object, error)

RawJSONMap splits a JSON object into raw fields. Values alias raw.

func (*Object) Get added in v0.4.0

func (o *Object) Get(name string) ([]byte, bool)

Get returns the raw bytes of the named member.

Lookup is a linear scan. Request bodies have few top-level fields, and comparing against a subslice beats hashing a freshly allocated key string.

func (*Object) Has added in v0.4.0

func (o *Object) Has(name string) bool

Has reports whether the named member is present.

func (*Object) Len added in v0.4.0

func (o *Object) Len() int

Len returns the number of members.

func (*Object) Member added in v0.4.3

func (o *Object) Member(i int) (name string, raw []byte)

Member returns the i'th member's name and raw value in document order. The raw bytes alias the buffer the Object was built from, like Get's.

func (*Object) Names added in v0.4.0

func (o *Object) Names(dst []string) []string

Names appends every member name to dst as strings.

func (*Object) RestAny added in v0.4.0

func (o *Object) RestAny(exclude []string) (map[string]any, error)

RestAny decodes members not named in exclude into a map of Go values.

func (*Object) RestNames added in v0.4.0

func (o *Object) RestNames(exclude []string) []string

RestNames returns the names of members not listed in exclude, in document order.

type Parser added in v0.4.0

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

Parser reads a JSON document in a single forward pass. Generated codecs drive it directly: values are parsed out of the input buffer in place, so decoding allocates only the strings, slices and maps that end up in the result.

It does not use reflect and does not import encoding/json.

func NewParser added in v0.4.0

func NewParser(data []byte) *Parser

NewParser returns a Parser reading data. data is not copied, and values returned by RawValue alias it.

func (*Parser) Any added in v0.4.0

func (p *Parser) Any() (any, error)

Any decodes an arbitrary JSON value into the same Go shapes encoding/json produces for an `any` destination.

func (*Parser) ArrayNext added in v0.4.0

func (p *Parser) ArrayNext(n int) (bool, error)

ArrayNext reports whether another element follows. n is the element index.

func (*Parser) ArrayStart added in v0.4.0

func (p *Parser) ArrayStart() (isNull bool, err error)

ArrayStart consumes '['. A JSON null reports isNull and consumes the literal.

func (*Parser) Bool added in v0.4.0

func (p *Parser) Bool() (bool, error)

Bool decodes a JSON boolean. null decodes as false.

func (*Parser) End added in v0.4.0

func (p *Parser) End() error

End reports an error when anything but whitespace follows the document.

func (*Parser) Float64 added in v0.4.0

func (p *Parser) Float64() (float64, error)

Float64 decodes a JSON number. null decodes as 0.

func (*Parser) Int added in v0.4.0

func (p *Parser) Int() (int, error)

Int decodes a JSON number as int. null decodes as 0.

func (*Parser) Int64 added in v0.4.0

func (p *Parser) Int64() (int64, error)

Int64 decodes a JSON number as int64. null decodes as 0.

func (*Parser) IsNull added in v0.4.0

func (p *Parser) IsNull() bool

IsNull consumes a null literal when the next value is null.

func (*Parser) ObjectKey added in v0.4.0

func (p *Parser) ObjectKey(n int) (key []byte, ok bool, err error)

ObjectKey returns the next member name, or ok=false at '}'. n is the zero-based member index and tells the parser whether a comma is required, so the parser needs no nesting stack of its own.

The returned key aliases parser scratch space and is only valid until the next ObjectKey call.

func (*Parser) ObjectStart added in v0.4.0

func (p *Parser) ObjectStart() (isNull bool, err error)

ObjectStart consumes '{'. A JSON null reports isNull and consumes the literal.

func (*Parser) RawValue added in v0.4.0

func (p *Parser) RawValue() ([]byte, error)

RawValue returns the next value's bytes as a subslice of the input. The result aliases the parser's buffer and must be copied to outlive it.

func (*Parser) Reset added in v0.4.0

func (p *Parser) Reset(data []byte)

Reset points p at data, reusing its scratch buffers.

func (*Parser) SkipValue added in v0.4.0

func (p *Parser) SkipValue() error

SkipValue advances past the next value, whatever its shape. Structure is validated; the value's contents are not interpreted.

func (*Parser) String added in v0.4.0

func (p *Parser) String() (string, error)

String decodes a JSON string. null decodes as "".

Jump to

Keyboard shortcuts

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