Documentation
¶
Overview ¶
Example ¶
package main
import (
"fmt"
"github.com/ivanjoz/minijson"
)
func main() {
type user struct {
Name string `json:"name"`
Age int `json:"age,omitempty"`
Tags []string `json:"tags,omitempty"`
}
users := []user{{Name: "Ada", Age: 36}, {Name: "Lin", Tags: []string{"admin"}}}
encoded, _ := minijson.Marshal(users)
var decoded []user
_ = minijson.Unmarshal(encoded, &decoded)
fmt.Println(decoded[0].Name, decoded[1].Tags[0])
}
Output: Ada admin
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IncludeEmpty ¶ added in v0.2.0
func IncludeEmpty() bool
IncludeEmpty reports whether payloads carry the per-type defaults block. Defaults to the MINIJSON_INCLUDE_EMPTY=1 environment variable so it can be switched without a code change.
func Marshal ¶
Marshal converts an object to the compact array format. Returns a single array with two elements: [keys, content]
- keys: type definitions mapping emit position -> field name (JSON tags)
- content: the serialized data, fields in emit order, zero values skipped
Single pass, written straight to bytes. The field emit order comes from the registry, frozen the first time a type is encountered and reused for every payload after that; the order travels with each payload in the keys header, so the decoder never needs to share the encoder's history. Field usage is tracked per call on the Encoder, and the keys header is rendered afterwards from it — which works because keys are prepended to the output.
func SetIncludeEmpty ¶ added in v0.2.0
func SetIncludeEmpty(enabled bool)
SetIncludeEmpty overrides the environment default. Takes effect on the next Marshal.
Types ¶
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
func NewDecoder ¶
func NewDecoder() *Decoder
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
func NewEncoder ¶
func NewEncoder() *Encoder
type FieldInfo ¶
type FieldInfo struct {
Index int // Position in TypeInfo.Fields, i.e. this field's own index
Name string // JSON tag name or field name
RawName string // Original field name (without JSON tag)
// OmitEmpty reports whether the json tag carries the omitempty option. It does not change
// what is written to the wire — zero values are always omitted — it selects which fields get
// an entry in the keys header's defaults block. See defaults.go.
OmitEmpty bool
// IndexPath locates the field inside the type: length 1 for a directly declared field, longer
// for one promoted out of an embedded struct. Walk it with fieldByIndexPath.
IndexPath []int
// Type is the field's own type, cached so decoding never has to re-resolve it per record.
Type reflect.Type
// contains filtered or unexported fields
}
FieldInfo stores metadata for one serializable field of a type.
"Serializable" means the field survived promotion: unexported fields and `json:"-"` fields are absent from TypeInfo.Fields entirely, and the fields of an anonymous embedded struct appear here in their own right rather than under the embedded type's name. See fields.go.
type FieldRegistry ¶
type FieldRegistry struct {
// contains filtered or unexported fields
}
FieldRegistry manages the mapping between types and their IDs
func NewFieldRegistry ¶
func NewFieldRegistry() *FieldRegistry
func (*FieldRegistry) GetTypeInfo ¶
func (r *FieldRegistry) GetTypeInfo(id int) *TypeInfo
type TypeInfo ¶
type TypeInfo struct {
ID int
Type reflect.Type
// Fields are the type's serializable fields, with embedded structs promoted. Every index used
// anywhere else — DefaultOrder, OptimizedOrder, the usage mask, the keys header — indexes into
// this slice, not into the Go struct's own fields.
Fields []FieldInfo
// DefaultOrder lists the field indices in declaration order. Precomputed so a type that has
// not been optimized yet does not rebuild this slice for every record.
DefaultOrder []int
// DefaultsBlock is the rendered {"field":<zero>,...} object for this type's non-omitempty
// fields, appended to the type's keys header entry when IncludeEmpty is on. Nil when the
// type has no such field. Built here so emitting it never costs more than a byte copy.
DefaultsBlock []byte
// OptimizedOrder / IsOptimized are written once under the registry lock and read-only after.
OptimizedOrder []int
IsOptimized bool
}
TypeInfo stores metadata for a registered type.
Everything here is derived from the Go type and is therefore immutable once built — it is shared across every concurrent Marshal. Per-response state (which fields a given payload actually used) lives on the Encoder instead; see encoderTypeUsage.
OptimizedOrder is the one field that is learned rather than derived. It is frozen from the first payload that carries the type and reused verbatim afterwards, which is what lets Marshal run a single pass. Freezing is safe because the order is transmitted in the payload's keys header on every response, so the decoder never depends on the encoder's history.