Documentation
¶
Overview ¶
zerojsongen generates zerojson codecs (AppendZJSON / UnmarshalZJSON) for the requested struct types. Emitted code encodes leaf types directly into an append buffer and decodes with a single arena allocation, enum switch dispatch, and tag-driven interning.
Usage:
go run github.com/neal/zerojson/cmd/zerojsongen -dir . -types A,B,C -out zerojson_gen.go
Rules (validate with byte-identity tests against your current encoder):
- field order = struct declaration order
- the json tag carries ONLY standard encoding/json options: the name, `-`, omitempty, omitzero, and string. Any other option (e.g. `,intern`) is a generate-time error naming the field and telling you to move it to a `zerojson:"..."` tag instead — this is enforced, not just documented, so a stray option can't silently do nothing.
- zerojson:"..." is a comma-separated list of custom options; `intern` is the only one today. Unknown zerojson options are also a generate-time error.
- omitempty gates: ptr != nil; string/enum != ""; named-int != 0; bool; slices len != 0. Value structs / time.Time / uuid.UUID cannot be gated by omitempty (matching easyjson and encoding/json v1, which cannot check their emptiness either) — use omitzero for those.
- omitzero (Go 1.24 stdlib semantics) gates on the zero value: an IsZero() bool method is honored if the type has one (time.Time and any user type that defines one); nil for pointers/slices/maps/interfaces; the usual scalar zero otherwise. easyjson ignores omitzero, so byte-identity does not extend to fields that use it — the one intentional divergence.
- string (stdlib "quoted" convention) is implemented for plain int/uint fields today: it encodes quoted and requires a quoted JSON token on decode. Other kinds are a generate-time "not yet supported" error, not silent mishandling.
- non-omitempty, non-omitzero pointer fields always emit the key, null when nil.
- named string types are treated as enums: decode switches over the type's declared constants. Unknown values are copied unless the field explicitly carries zerojson:"intern".
- named int64 types implementing MarshalJSON may opt into the direct quoted-string fast path with a ZeroJSONQuotedInt64() marker method. Without that explicit promise their methods are delegated normally.
- other types with MarshalJSON/UnmarshalJSON delegate to those methods (always correct, slower). NOTE: their output is appended verbatim, matching easyjson; encoding/json would re-compact it.
Source layout: this file holds flags, main(), and the generator driver. load.go collects and classifies struct fields from the loaded package. encode.go/decode.go emit AppendZJSON/UnmarshalZJSON bodies (and, for decode, the ordered speculative fast path in ordered.go). compat.go emits json.Marshaler/easyjson wrappers, pool.go the reusable-arena Decoder, and tests_emit.go the differential fuzz tests.