Type-driven JSON: parse straight into the caller's chosen type and
serialize from it, with no generic Value middle layer.
json-bourne skips the dynamic-tree intermediate that crates like
serde_json use. Each type knows how to deserialize itself from a
[Lexer] (via FromJson) or write itself to a [JsonWrite]
sink (via [ToJson]). The typed structure already enforces JSON's
grammar, so the per-event state machine is pure overhead for typed
consumers — skipping it makes the typed path ~2× faster on
integer / string-heavy payloads.
- No proc-macros. [
from_json!], [to_json!], and [json!] are declarativemacro_rules!. Empty dependency graph. no_stdeverywhere. The streaming [Lexer] / [Parser] layer isno_stdalways; with the defaultstdfeature off the crate isno_std + alloc, and withallocoff too it is pureno_std.- Borrowed strings by default.
&'input strandCow<'input, str>parse zero-copy when the input contains no escapes. - Bounded by construction. Container nesting is depth-limited (default 128, const-generic). The streaming parser is a state machine with no recursion.
Quick start
Parse a primitive directly into a Rust type:
use parse_str;
let n: u32 = parse_str.unwrap;
assert_eq!;
Parse a struct (no proc-macro — from_json! is declarative):
use ;
from_json!
let u: = parse_str.unwrap;
assert_eq!;
Serialize back out:
use ;
to_json!
let s = to_string.unwrap;
assert_eq!;
Output destinations
| Sink | Entry point |
|---|---|
String |
[to_string] |
Vec<u8> |
[to_vec] |
String (pretty-printed) |
[to_string_pretty] |
any [std::io::Write] |
[to_writer] (std only) |
any [core::fmt::Write] |
[to_fmt] |
Custom sinks implement [JsonWrite] directly.
Features
| Feature | Default | Purpose |
|---|---|---|
std |
yes | HashMap, std::net, std::path, to_writer |
alloc |
yes | String, Vec, Box/Rc/Arc, escape decoding |
indexmap |
no | IndexMap / IndexSet (insertion order) |
default-features = false plus ["alloc"] gives a no_std + alloc
build. default-features = false alone gives pure no_std: only the
streaming [Lexer] / [Parser] and typed APIs that don't need a
heap (e.g. parsing into stack-allocated primitives) are available.