json_session/
lib.rs

1//! Streaming parser for JSON. The main type is [`JsonSession`], which consumes an iterator over
2//! bytes and yields [`JsonFragmentWithSpan`] values. [`JsonFragment`] has the following enum variants:
3//! `BeginObject`, `ObjectProperty`, `EndObject`, `BeginArray`, `EndArray`, and `PrimitiveValue`.
4//!
5//! Every yielded value has a [`LocationSpan`] attached to it, saying at which byte offset
6//! (and at which line and column) the fragment begins and ends.
7//!
8//! This API allows gathering statistics about the contents of large JSON documents without ever
9//! holding the entire document in memory.
10//!
11//! ```
12//! use json_session::{JsonSession, JsonFragment, JsonPrimitiveValue};
13//!
14//! # fn main() {
15//! let input_str = r#"{"key1": 1234, "key2": [true], "key3": "value" }"#;
16//! let expected = &[
17//!     JsonFragment::BeginObject,
18//!     JsonFragment::ObjectProperty(String::from("key1")),
19//!     JsonFragment::PrimitiveValue(JsonPrimitiveValue::Number(1234.0)),
20//!     JsonFragment::ObjectProperty(String::from("key2")),
21//!     JsonFragment::BeginArray,
22//!     JsonFragment::PrimitiveValue(JsonPrimitiveValue::Boolean(true)),
23//!     JsonFragment::EndArray,
24//!     JsonFragment::ObjectProperty(String::from("key3")),
25//!     JsonFragment::PrimitiveValue(JsonPrimitiveValue::String(String::from("value"))),
26//!     JsonFragment::EndObject,
27//! ];
28//! let mut session = JsonSession::new(input_str.as_bytes().iter().cloned());
29//! for expected_fragment in expected {
30//!     let fragment = session.next().unwrap().unwrap().fragment;
31//!     assert_eq!(fragment, *expected_fragment);
32//! }
33//! assert!(session.next().unwrap().is_none());
34//! # }
35//! ```
36//!
37//! [`JsonSession`] checks that the JSON is valid, and only returns a sequence of fragments
38//! that describe valid JSON. If an invalid sequence of bytes or tokens is detected,
39//! [`JsonSession::next`] yields an error.
40//!
41//! This crate also exposes the tokenizer and  token types that are used internally, but
42//! you can ignore them.
43
44mod session;
45mod tokenizer;
46
47pub use session::*;
48pub use tokenizer::*;