A JSON parser written from scratch, without serde_json. The defining
feature: parsed strings borrow directly from the input &str instead of
allocating a new String for every string in the document.
- Zero-copy string parsing:
Value<'a>strings areCow<'a, str>. A JSON string with no escape sequences is returned asCow::Borrowed, a direct slice of the original input, zero heap allocation. A string containing an escape (\n,\",\uXXXX, ...) can't be represented as a contiguous slice of the original bytes, since decoding the escape changes the bytes, so that case falls back toCow::Owned. This is the same borrowed-or-owned split serde's own zero-copy deserializers use. - Hand-written lexer and recursive-descent parser: a byte-level lexer with one token of lookahead, no parser generator or combinator library.
- UTF-16 surrogate pairs:
\uXXXXescapes outside the Basic Multilingual Plane arrive as a high/low surrogate pair (\uD834\uDD1E); the lexer decodes the pair into the single resultingchar. - Order-preserving objects:
ObjectisVec<(Cow<str>, Value)>, not aHashMap, so this stays dependency-free and keeps keys in the order they appeared in the source, which a hash map wouldn't.
let value = zero_copy_json::parse(r#"{"name": "test", "count": 42}"#)?;Returns Result<Value<'_>, JsonError>. JsonError carries the byte offset
into the original input where parsing failed.
Implements enough of RFC 8259 to be a useful, readable reference: objects,
arrays, strings with escapes and surrogate pairs, numbers, booleans, null.
It is not a fully spec-validating parser: for example it accepts a leading
zero like 01 as a number, which strict JSON forbids. That's intentional,
in favor of a smaller, more readable implementation over full spec
conformance.
cargo test