nop-json
nop-json is a streaming JSON reader and writer for Rust. It deserializes a byte stream directly
into your own types and serializes them back, without building an intermediate document — unless
you ask for one.
Features
- Streaming, low-allocation parsing. A
Readerconsumes anyIterator<Item=u8>— a&str, a&[u8], a file, a socket — and reads one value at a time. - Reads straight into Rust types. Any type implementing
TryFromJsoncan be read withreader.read(). It's provided for primitives,String,char,Option,Box,Rc,Arc,Vec,HashMap,BTreeMap, sets, tuples and more, and can be derived for your own structs and enums with#[derive(TryFromJson)]. - Serializes back to JSON with
#[derive(DebugToJson)](which also gives you a JSONDebugimpl, soprintln!("{:?}", x)andx.to_json_string()produce JSON) or#[derive(WriteToJson)](which writes to anyio::Write). - Sequences: one
Readerreads many whitespace-separated values from a single stream. - Binary blobs: smuggle arbitrary bytes (
0x00–0xFF) through JSON strings and read them back, or stream them to a writer withpipe_blob. - Safe on untrusted input: configurable nesting-depth and value-size limits (see below).
Installation
[]
= "2.1"
Quick start
use ;
let mut reader = new;
let point: Point = reader.read.unwrap;
assert_eq!;
// ...and serialize it back
assert_eq!;
The JSON dialect
nop-json accepts the JSON grammar of ECMA-404, plus a few conveniences inspired by JavaScript's
own value conversions:
- Lenient coercion on read: a JSON string holding a number (
"123") can be read into a numeric type, a number can be read into aString, andtrue/false/nullread into a number give1/0/0. - Non-finite floats travel as JSON strings:
f32/f64infinities and NaN serialize as"Infinity","-Infinity"and"NaN", and those strings read back to the matching values. - It is not JSON5: comments, single-quoted strings, unquoted keys, hexadecimal numbers and bare
Infinity/NaNare not accepted.
Reading untrusted input
A Reader enforces two limits to stay safe against hostile input. Override them with
ReaderBuilder:
use ReaderBuilder;
let mut reader = new
.depth_limit // max array/object nesting (default 256)
.value_size_limit // max bytes of one string or blob (default 1 GiB)
.build;
depth_limit bounds parser recursion, so input nested deeper than the limit returns an error
instead of overflowing the stack. value_size_limit caps the size of a single in-memory string or
blob.
Documentation
Full API reference and more examples: docs.rs/nop-json.