pub struct JsonReader<'a, B: AsMut<[u8]>, R: BlockingRead> { /* private fields */ }Expand description
A JsonReader wraps a sequence of bytes, aggregating them into a sequence of JSON tokens. It is in essentially a tokenizer, adding some rudimentary convenience for JSON’s grammar.
It does not try to be a full-blown JSON parser. The reason is that if an application consumes an actual JSON document, it assumes structure beyond the document being a valid JSON document (‘name is a mandatory string, age is a u32, but it is ok if it is null or not present in the first place’). JsonReader makes it easy for application code to consume data based on such assumptions - and while it does, application code checks the document’s conformity to the JSON grammar automatically.
A JsonReader wraps and consumes a BlockingRead which is basically a same abstraction as a
std::io::Read but without enforcing the dependency on std. For the majority of users who
don’t care about that, there is a blanket implementation of BlockingRead for std::io::Read,
letting you ignore distinction between the two.
The JsonReader holds a mutable reference to the reader rather than taking ownership of it. That means it needs to have a lifetime parameter, allowing the compiler to ensure that the reader lives at least as long as the wrapping JsonReader.
The JsonReader also holds a fixed read buffer which it uses to assemble tokens. JsonReader can either work with a buffer passed to it on construction, or it can allocate the buffer as a convenience, and it does not do any memory allocation on the heap beyond that.
The buffer is fixed in length, and if some token (e.g. a string value) does not fit into the buffer, that causes a failure. While this may look like an inconvenient restriction, it is actually an important security safeguard: JSON documents often come from external sources and have limited trustworthiness at best. Without an upper bound on token size, a maliciously or negligently created document could contain a string literal with a size of a gigabyte, working as a denial-of-service attack. JSON parsers that work on materialized documents often address this by placing a restriction on the maximum size of the whole document.
The following code snippet shows a small working example of reading a JSON document with a single object:
use json_streaming::blocking::*;
use json_streaming::shared::*;
fn read_something(r: &mut impl std::io::Read) -> JsonParseResult<(), std::io::Error> {
let mut json_reader = JsonReader::new(1024, r);
json_reader.expect_start_object()?;
loop {
match json_reader.expect_key()? {
Some("a") => println!("a: {}", json_reader.expect_string()?),
Some("b") => println!("b: {}", json_reader.expect_string()?),
Some(_other) => {
return Err(JsonParseError::Parse("unexpected key parsing 'person'", json_reader.location()));
},
None => break,
}
}
Ok(())
}Implementations§
Source§impl<'a, R: BlockingRead> JsonReader<'a, Vec<u8>, R>
impl<'a, R: BlockingRead> JsonReader<'a, Vec<u8>, R>
Sourcepub fn new(buf_size: usize, reader: &'a mut R) -> Self
pub fn new(buf_size: usize, reader: &'a mut R) -> Self
Create a JsonReader, allocating a read buffer of given size on the heap.
Sourcepub fn new_with_lenient_comma_handling(
buf_size: usize,
reader: &'a mut R,
) -> Self
pub fn new_with_lenient_comma_handling( buf_size: usize, reader: &'a mut R, ) -> Self
Create a JsonReader without requiring commas between objects. This is intended for
reading [https://jsonlines.org] documents - see the jsonlines.rs example for details.
Source§impl<'a, B: AsMut<[u8]>, R: BlockingRead> JsonReader<'a, B, R>
impl<'a, B: AsMut<[u8]>, R: BlockingRead> JsonReader<'a, B, R>
Sourcepub fn new_with_provided_buffer(
buf: B,
reader: &'a mut R,
lenient_comma_handling: bool,
) -> Self
pub fn new_with_provided_buffer( buf: B, reader: &'a mut R, lenient_comma_handling: bool, ) -> Self
Create a JsonReader that uses an externally provided buffer as its read buffer. The main reason to do this is to avoid heap allocation in a no-std environment.
Sourcepub fn next(&mut self) -> JsonParseResult<JsonReadToken<'_>, R::Error>
pub fn next(&mut self) -> JsonParseResult<JsonReadToken<'_>, R::Error>
Return the next JSON token. This is the work horse of JsonReader and the foundation for other convenience abstraction.
The function does only limited checks of JSON grammar and basically returns whatever tokens it finds.
Sourcepub fn expect_key(&mut self) -> JsonParseResult<Option<&str>, R::Error>
pub fn expect_key(&mut self) -> JsonParseResult<Option<&str>, R::Error>
This is the function for the loop to read the members of a JSON object: It returns either
a JSON key or None if it encounters the } that ends the object. All other tokens are
invalid and cause the function to fail.
Sourcepub fn expect_raw_number(&mut self) -> JsonParseResult<JsonNumber<'_>, R::Error>
pub fn expect_raw_number(&mut self) -> JsonParseResult<JsonNumber<'_>, R::Error>
Returns a JSON number as a JsonNumber, and fails if the next token is anything other
than a number. That includes the case that the next token is null - if the number
is optional and null a valid value, use JsonReader::expect_opt_raw_number instead.
Sourcepub fn expect_raw_number_or_end_array(
&mut self,
) -> JsonParseResult<Option<JsonNumber<'_>>, R::Error>
pub fn expect_raw_number_or_end_array( &mut self, ) -> JsonParseResult<Option<JsonNumber<'_>>, R::Error>
Same as JsonReader::expect_raw_number, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_opt_raw_number(
&mut self,
) -> JsonParseResult<Option<JsonNumber<'_>>, R::Error>
pub fn expect_opt_raw_number( &mut self, ) -> JsonParseResult<Option<JsonNumber<'_>>, R::Error>
Returns a JsonNumber if the next token is a JSON number, or None if the next token
is null. All other tokens cause the function to fail.
Sourcepub fn expect_opt_raw_number_or_end_array(
&mut self,
) -> JsonParseResult<Option<Option<JsonNumber<'_>>>, R::Error>
pub fn expect_opt_raw_number_or_end_array( &mut self, ) -> JsonParseResult<Option<Option<JsonNumber<'_>>>, R::Error>
Same as JsonReader::expect_opt_raw_number, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_number<T: FromStr>(&mut self) -> JsonParseResult<T, R::Error>
pub fn expect_number<T: FromStr>(&mut self) -> JsonParseResult<T, R::Error>
Returns a number parsed to an application-provided type, failing if the next token is not a JSON number or the number is not parseable to the provided type (e.g. trying to get retrieve a floating point number as a u32).
The expected numeric type can be provided explicitly, like this:
let n = json_reader.expect_number::<u32>()?;or inferred by the compiler:
let n:u32 = json_reader.expect_number()?;Sourcepub fn expect_number_or_end_array<T: FromStr>(
&mut self,
) -> JsonParseResult<Option<T>, R::Error>
pub fn expect_number_or_end_array<T: FromStr>( &mut self, ) -> JsonParseResult<Option<T>, R::Error>
Same as JsonReader::expect_number, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_opt_number<T: FromStr>(
&mut self,
) -> JsonParseResult<Option<T>, R::Error>
pub fn expect_opt_number<T: FromStr>( &mut self, ) -> JsonParseResult<Option<T>, R::Error>
The same as JsonReader::expect_number, but accepting a null literal which it
returns as None.
Sourcepub fn expect_opt_number_or_end_array<T: FromStr>(
&mut self,
) -> JsonParseResult<Option<Option<T>>, R::Error>
pub fn expect_opt_number_or_end_array<T: FromStr>( &mut self, ) -> JsonParseResult<Option<Option<T>>, R::Error>
Same as JsonReader::expect_opt_number, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_string(&mut self) -> JsonParseResult<&str, R::Error>
pub fn expect_string(&mut self) -> JsonParseResult<&str, R::Error>
If the next token is a string literal, return that, and fail for any other token.
Sourcepub fn expect_string_or_end_array(
&mut self,
) -> JsonParseResult<Option<&str>, R::Error>
pub fn expect_string_or_end_array( &mut self, ) -> JsonParseResult<Option<&str>, R::Error>
Same as JsonReader::expect_string, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_opt_string(&mut self) -> JsonParseResult<Option<&str>, R::Error>
pub fn expect_opt_string(&mut self) -> JsonParseResult<Option<&str>, R::Error>
The same as JsonReader::expect_string, but accepting a null literal which is
returned as None.
Sourcepub fn expect_opt_string_or_end_array(
&mut self,
) -> JsonParseResult<Option<Option<&str>>, R::Error>
pub fn expect_opt_string_or_end_array( &mut self, ) -> JsonParseResult<Option<Option<&str>>, R::Error>
Same as JsonReader::expect_opt_string, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_bool(&mut self) -> JsonParseResult<bool, R::Error>
pub fn expect_bool(&mut self) -> JsonParseResult<bool, R::Error>
true and false literals are returned as a boolean token, all other tokens cause the
function to fail.
Sourcepub fn expect_bool_or_end_array(
&mut self,
) -> JsonParseResult<Option<bool>, R::Error>
pub fn expect_bool_or_end_array( &mut self, ) -> JsonParseResult<Option<bool>, R::Error>
Same as JsonReader::expect_bool, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_opt_bool(&mut self) -> JsonParseResult<Option<bool>, R::Error>
pub fn expect_opt_bool(&mut self) -> JsonParseResult<Option<bool>, R::Error>
The same as JsonReader::expect_bool, but accepting a null literal which is
returned as None.
Sourcepub fn expect_opt_bool_or_end_array(
&mut self,
) -> JsonParseResult<Option<Option<bool>>, R::Error>
pub fn expect_opt_bool_or_end_array( &mut self, ) -> JsonParseResult<Option<Option<bool>>, R::Error>
Same as JsonReader::expect_opt_bool, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_start_object(&mut self) -> JsonParseResult<(), R::Error>
pub fn expect_start_object(&mut self) -> JsonParseResult<(), R::Error>
Fails for any token except the { that starts an object.
Sourcepub fn expect_start_object_or_end_array(
&mut self,
) -> JsonParseResult<Option<()>, R::Error>
pub fn expect_start_object_or_end_array( &mut self, ) -> JsonParseResult<Option<()>, R::Error>
Same as [JsonReader::start_object], except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_opt_start_object(
&mut self,
) -> JsonParseResult<Option<()>, R::Error>
pub fn expect_opt_start_object( &mut self, ) -> JsonParseResult<Option<()>, R::Error>
The same as JsonReader::expect_start_object, but accepting a null literal which is
returned as None.
Sourcepub fn expect_opt_start_object_or_end_array(
&mut self,
) -> JsonParseResult<Option<Option<()>>, R::Error>
pub fn expect_opt_start_object_or_end_array( &mut self, ) -> JsonParseResult<Option<Option<()>>, R::Error>
Same as JsonReader::expect_opt_start_object, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_end_object(&mut self) -> JsonParseResult<(), R::Error>
pub fn expect_end_object(&mut self) -> JsonParseResult<(), R::Error>
Fails for any token except the } that ends an object.
Sourcepub fn expect_start_array(&mut self) -> JsonParseResult<(), R::Error>
pub fn expect_start_array(&mut self) -> JsonParseResult<(), R::Error>
Fails for any token except the [ that starts an array.
Sourcepub fn expect_start_array_or_end_array(
&mut self,
) -> JsonParseResult<Option<()>, R::Error>
pub fn expect_start_array_or_end_array( &mut self, ) -> JsonParseResult<Option<()>, R::Error>
Same as JsonReader::expect_start_array, except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_opt_start_array(
&mut self,
) -> JsonParseResult<Option<()>, R::Error>
pub fn expect_opt_start_array( &mut self, ) -> JsonParseResult<Option<()>, R::Error>
The same as JsonReader::expect_start_array, but accepting a null literal which is
returned as None.
Sourcepub fn expect_opt_start_array_or_end_array(
&mut self,
) -> JsonParseResult<Option<Option<()>>, R::Error>
pub fn expect_opt_start_array_or_end_array( &mut self, ) -> JsonParseResult<Option<Option<()>>, R::Error>
Same as [JsonReader::opt_start_array], except that it returns Ok(None) if it reaches the end of an
array instead
Sourcepub fn expect_end_array(&mut self) -> JsonParseResult<(), R::Error>
pub fn expect_end_array(&mut self) -> JsonParseResult<(), R::Error>
Fails for any token except the ] that ends an array.
Sourcepub fn expect_end_of_stream(&mut self) -> JsonParseResult<(), R::Error>
pub fn expect_end_of_stream(&mut self) -> JsonParseResult<(), R::Error>
Fails if the stream contains any tokens - this is for checking that the entire JSON input was consumed
Sourcepub fn skip_to_end_of_current_scope(&mut self) -> JsonParseResult<(), R::Error>
pub fn skip_to_end_of_current_scope(&mut self) -> JsonParseResult<(), R::Error>
This function assumes that it is called inside an object or array, and silently consumes
all tokens until and including the closing } or ].
This function is useful for gracefully ignoring array elements with an unsupported type. See
the skipping.rs example for details.
Sourcepub fn skip_value(&mut self) -> JsonParseResult<(), R::Error>
pub fn skip_value(&mut self) -> JsonParseResult<(), R::Error>
This function skips the value starting with the next token. This can be a single-token value,
but it can also be an object or array of unknown structure and nesting depth, in which
case this function silently consumes tokens until it reaches the matching closing } or
].
This function is useful for gracefully ignoring object members with an unknown key - see
the skipping.rs example for details.
Sourcepub fn parse_err<T>(&self, msg: &'static str) -> JsonParseResult<T, R::Error>
pub fn parse_err<T>(&self, msg: &'static str) -> JsonParseResult<T, R::Error>
convenience function for creating a parse error with the current location