SIMD-accelerated, lazy JSON field extraction for the Odin programming language.
ojson parses JSON lazily: it walks the full document to index structure and positions, but defers type conversion and string unescaping until you read a field. SIMD-accelerated string and number scanning. Includes a code generator for type-safe unmarshalling and marshalling.
- Lazy parsing with deferred type conversion
- SIMD-accelerated string and number scanning
- Reusable reader that amortizes allocation across many messages
- Code generation for struct unmarshalling and marshalling
omitemptysupport for skipping zero-valued fields during marshal
# Add as a submodule or copy to your project
git clone https://github.com/jonathan-rowles/ojsonFor parsing many messages:
import oj "ojson"
r: oj.Reader
oj.init_reader(&r)
defer oj.destroy(&r)
for msg in messages {
oj.parse(&r, msg)
name, _ := oj.read_string(&r, "users.0.name")
items, _ := oj.array_elements(&r, "items")
for item in items {
price, _ := oj.read_f64_elem(&r, item, "price")
}
}For single lookups:
name, _ := oj.get_string(data, "user.name")// types.odin
Item :: struct {
name: string `json:"name"`,
price: f64 `json:"price"`,
}
Order :: struct {
id: i64 `json:"id"`,
items: []Item `json:"items"`,
note: string `json:"note,omitempty"`,
}make generate SRC=../myproject/typesGenerates both unmarshal_* and marshal_* procs for each struct:
import oj "ojson"
import oj_gen "ojson/gen"
r: oj.Reader
oj.init_reader(&r)
defer oj.destroy(&r)
// Unmarshal
oj.parse(&r, data)
order, err := oj_gen.unmarshal_order(&r)
// Marshal
w := oj.init_writer()
defer oj.destroy(&w)
oj_gen.marshal_order(&w, order)
result := oj.writer_string(&w)Fields tagged with omitempty are skipped during marshal when they have their zero value ("" for strings, 0 for numbers, false for bools, empty for slices).
The following types are not currently supported by the code generator:
- Pointers (
^T): detected by the parser but generated code won't compile - Maps (
map[K]V)