pub trait JsonReader {
Show 25 methods // Required methods fn peek(&mut self) -> Result<ValueType, ReaderError>; fn begin_object(&mut self) -> Result<(), ReaderError>; fn end_object(&mut self) -> Result<(), ReaderError>; fn begin_array(&mut self) -> Result<(), ReaderError>; fn end_array(&mut self) -> Result<(), ReaderError>; fn has_next(&mut self) -> Result<bool, ReaderError>; fn next_name(&mut self) -> Result<&str, ReaderError>; fn next_name_owned(&mut self) -> Result<String, ReaderError>; fn next_str(&mut self) -> Result<&str, ReaderError>; fn next_string(&mut self) -> Result<String, ReaderError>; fn next_string_reader(&mut self) -> Result<impl Read + '_, ReaderError>; fn next_number_as_str(&mut self) -> Result<&str, ReaderError>; fn next_number_as_string(&mut self) -> Result<String, ReaderError>; fn next_bool(&mut self) -> Result<bool, ReaderError>; fn next_null(&mut self) -> Result<(), ReaderError>; fn deserialize_next<'de, D: Deserialize<'de>>( &mut self ) -> Result<D, DeserializerError>; fn skip_name(&mut self) -> Result<(), ReaderError>; fn skip_value(&mut self) -> Result<(), ReaderError>; fn skip_to_top_level(&mut self) -> Result<(), ReaderError>; fn transfer_to<W: JsonWriter>( &mut self, json_writer: &mut W ) -> Result<(), TransferError>; fn consume_trailing_whitespace(self) -> Result<(), ReaderError>; fn current_position(&self, include_path: bool) -> JsonReaderPosition; // Provided methods fn next_number<T: FromStr>( &mut self ) -> Result<Result<T, T::Err>, ReaderError> { ... } fn seek_to(&mut self, rel_json_path: &JsonPath) -> Result<(), ReaderError> { ... } fn seek_back(&mut self, rel_json_path: &JsonPath) -> Result<(), ReaderError> { ... }
}
Expand description

A trait for JSON readers

The methods of this reader can be divided into the following categories:

JSON documents have at least one top-level value which can be either a JSON array, object, string, number, boolean or null value. For JSON arrays and objects the opening brackets must be consumed with the corresponding begin_ method (for example begin_array) and the closing bracket with the corresponding end_ method (for example end_array). JSON objects consist of members which are name-value pairs. The name of a member can be read with next_name and the value with any of the value reading methods such as next_bool.

It is not necessary to consume the complete JSON document, for example a user of this reader can simply drop the reader once the relevant information was extracted, ignoring the remainder of the JSON data. However, in that case no validation will be performed that the remainder has actually valid JSON syntax. To ensure that, skip_to_top_level can be used to skip (and validate) the remainder of the current top-level JSON array or object.

Important: Even after the top-level has been fully consumed this reader does not automatically consume the remainder of the JSON document (which is expected to consist of optional whitespace only). To verify that there is no trailing data it is necessary to explicitly call consume_trailing_whitespace.

§Examples

// In this example JSON data comes from a string;
// normally it would come from a file or a network connection
let json = r#"{"a": [1, 2, true]}"#;
let mut json_reader = JsonStreamReader::new(json.as_bytes());

json_reader.begin_object()?;
assert_eq!(json_reader.next_name()?, "a");

json_reader.begin_array()?;
assert_eq!(json_reader.next_number::<u32>()??, 1);
json_reader.skip_value()?;
assert_eq!(json_reader.next_bool()?, true);
json_reader.end_array()?;

json_reader.end_object()?;
// Ensures that there is no trailing data
json_reader.consume_trailing_whitespace()?;

§Error handling

The methods of this reader return a Result::Err when an error occurs while reading the JSON document. The error can for example be caused by an IO error from the underlying reader, a JSON syntax error or an unexpected structure of the JSON document. See ReaderError for more details.

When encountering ReaderError::SyntaxError and ReaderError::IoError processing the JSON document must be aborted. Trying to call any reader methods afterwards can lead to unspecified behavior, such as errors, panics or incorrect data. However, no undefined behavior occurs.

When encountering ReaderError::UnexpectedValueType or ReaderError::UnexpectedStructure depending on the use case it might be possible to continue processing the JSON document (except for seek_to where it might not be obvious how many elements have already been skipped). However, these errors can usually be avoided by using either peek or has_next before trying to consume a value whose type is not known in advance, or for which it is not known whether it is present in the JSON document.

In general it is recommended to handle errors with the ? operator of Rust, for example json_reader.next_bool()? and to abort processing the JSON document when an error occurs.

§Panics

Methods of this reader panic when used in an incorrect way. The documentation of the methods describes in detail the situations when that will happen. In general all these cases are related to incorrect usage by the user (such as trying to call end_object when currently reading a JSON array) and are unrelated to the JSON data which is processed.

Required Methods§

source

fn peek(&mut self) -> Result<ValueType, ReaderError>

Peeks at the type of the next value, without consuming it

Peeking at the type of a value can be useful when the exact structure of a JSON document is not known in advance, or when a value could be of more than one type. The value can then be consumed with one of the other methods.

This method does not guarantee that the peeked value is complete or valid; consuming it (with a separate method call) can return an error when malformed JSON data is detected.

§Examples
match json_reader.peek()? {
    ValueType::Boolean => println!("A boolean: {}", json_reader.next_bool()?),
    ValueType::String => println!("A string: {}", json_reader.next_str()?),
    _ => panic!("Unexpected type"),
}
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The method has_next can be used to check if there is a next value.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn begin_object(&mut self) -> Result<(), ReaderError>

Begins consuming a JSON object

The method has_next can be used to check if there is a next object member. To consume a member first call next_name or next_name_owned and afterwards one of the value reading methods such as next_number. At the end call end_object to consume the closing bracket of the JSON object.

§Examples
let mut json_reader = JsonStreamReader::new(r#"{"a": 1, "b": 2}"#.as_bytes());
json_reader.begin_object()?;

// Prints "a: 1", "b: 2"
while json_reader.has_next()? {
    let name = json_reader.next_name_owned()?;
    let value: u32 = json_reader.next_number()??;
    println!("{name}: {value}");
}

json_reader.end_object()?;
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

If the next value is not a JSON object but is a value of a different type a ReaderError::UnexpectedValueType is returned. The peek method can be used to check the type if it is not known in advance.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn end_object(&mut self) -> Result<(), ReaderError>

Consumes the closing bracket } of the current JSON object

This method is used to end a JSON object started by begin_object.

§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there are remaining members in the object a ReaderError::UnexpectedStructure is returned. skip_name and skip_value can be used to skip these remaining members in case they should be ignored:

while json_reader.has_next()? {
    // Skip member name
    json_reader.skip_name()?;
    // Skip member value
    json_reader.skip_value()?;
}

json_reader.end_object()?;
§Panics

Panics when called on a JSON reader which is currently not inside a JSON object, or when the value of a member is currently expected. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn begin_array(&mut self) -> Result<(), ReaderError>

Begins consuming a JSON array

The method has_next can be used to check if there is a next array item. To consume an item one of the regular value reading methods such as next_number can be used. At the end call end_array to consume the closing bracket of the JSON array.

Note that JSON arrays can contain values of different types, so for example the following is valid JSON: [1, true, "a"]

§Examples
let mut json_reader = JsonStreamReader::new("[1, 2, 3]".as_bytes());
json_reader.begin_array()?;

// Prints: "Number: 1", "Number: 2", "Number: 3"
while json_reader.has_next()? {
    let number: u32 = json_reader.next_number()??;
    println!("Number: {number}");
}

json_reader.end_array()?;
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

If the next value is not a JSON array but is a value of a different type a ReaderError::UnexpectedValueType is returned. The peek method can be used to check the type if it is not known in advance.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn end_array(&mut self) -> Result<(), ReaderError>

Consumes the closing bracket ] of the current JSON array

This method is used to end a JSON array started by begin_array.

§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there are remaining items in the array a ReaderError::UnexpectedStructure is returned. skip_value can be used to skip these remaining items in case they should be ignored:

while json_reader.has_next()? {
    json_reader.skip_value()?;
}

json_reader.end_array()?;
§Panics

Panics when called on a JSON reader which is currently not inside a JSON array. This indicates incorrect usage by the user and is unrelated to the JSON data.

source

fn has_next(&mut self) -> Result<bool, ReaderError>

Checks if there is a next element in the current JSON array or object, without consuming it

Returns true if there is a next element, false otherwise. When multiple top-level values are allowed by the ReaderSettings this method can also be used to check if there are more top-level values.

This method can be useful as condition of a while loop when processing a JSON array or object of unknown size.

§Examples
let mut json_reader = JsonStreamReader::new("[1]".as_bytes());
json_reader.begin_array()?;

// Array has a next item
assert!(json_reader.has_next()?);

json_reader.skip_value()?;
// Array does not have a next item anymore
assert_eq!(json_reader.has_next()?, false);
§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

Additionally this method also panics when called on a JSON reader which has not consumed any top-level value yet. An empty JSON document is not valid so there should be no need to check for a next element since there must always be one.

source

fn next_name(&mut self) -> Result<&str, ReaderError>

Consumes and returns the name of the next JSON object member as str

The name is returned as borrowed str. While that value is in scope, the Rust compiler might not permit using the JSON reader in any other way. If an owned String is needed, prefer next_name_owned, that will most likely be more efficient than using this method to obtain a str and then converting that to an owned String.

Afterwards one of the value reading methods such as next_number can be used to read the corresponding member value.

Important: This method does not detect duplicate member names, such as in {"a": 1, "a": 2}. Programs processing JSON data from an untrusted source must implement this detection themselves to protect against exploits relying on different handling of duplicate names by different JSON parsing libraries.

§Examples
let mut json_reader = JsonStreamReader::new(r#"{"a": 1}"#.as_bytes());
json_reader.begin_object()?;
assert_eq!(json_reader.next_name()?, "a");
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next object member a ReaderError::UnexpectedStructure is returned. has_next can be used to check if there are further members in the current JSON object.

§Panics

Panics when called on a JSON reader which currently does not expect a member name. This indicates incorrect usage by the user and is unrelated to the JSON data.

source

fn next_name_owned(&mut self) -> Result<String, ReaderError>

Consumes and returns the name of the next JSON object member as String

The name is returned as owned String. If a borrowed str suffices for your use case, prefer next_name, that will most likely be more efficient.

See the documentation of next_name for a detailed description of the behavior of reading a member name.

source

fn next_str(&mut self) -> Result<&str, ReaderError>

Consumes and returns a JSON string value as str

This method is only intended to consume string values, it cannot be used to consume JSON object member names. The method next_name has to be used for that.

The string value is returned as borrowed str. While that value is in scope, the Rust compiler might not permit using the JSON reader in any other way. If an owned String is needed, prefer next_string, that will most likely be more efficient than using this method to obtain a str and then converting that to an owned String.

To avoid reading the complete string value into memory, the method next_string_reader can be used to obtain a reader which allows lazily reading the value. Especially for large string values this can be useful.

§Examples
let mut json_reader = JsonStreamReader::new(r#""text with \"quotes\"""#.as_bytes());
assert_eq!(json_reader.next_str()?, "text with \"quotes\"");
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

If the next value is not a JSON string value but is a value of a different type a ReaderError::UnexpectedValueType is returned. The peek method can be used to check the type if it is not known in advance.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn next_string(&mut self) -> Result<String, ReaderError>

Consumes and returns a JSON string value as String

The string value is returned as owned String. If a borrowed str suffices for your use case, prefer next_str, that will most likely be more efficient.

See the documentation of next_str for a detailed description of the behavior of reading a string value.

source

fn next_string_reader(&mut self) -> Result<impl Read + '_, ReaderError>

Provides a reader for lazily reading a JSON string value

This method is mainly designed to process large string values in a memory efficient way. If that is not a concern the method next_str should be used instead.

This method is only intended to consume string values, it cannot be used to consume JSON object member names. The method next_name has to be used for that.

Escape sequences will be automatically converted to the corresponding characters.

Important: The data of the string value reader must be fully consumed, that means read has to be called with a non-empty buffer until it returns Ok(0). Otherwise the string value reader will still be considered ‘active’ and all methods of this JSON reader will panic. Note that after finishing reading from the string value reader, it might be necessary to explicitly drop(...) it for the Rust compiler to allow using the original JSON reader again.

§Examples
let mut json_reader = JsonStreamReader::new(r#"["hello"]"#.as_bytes());
json_reader.begin_array()?;

let mut string_reader = json_reader.next_string_reader()?;
let mut buf = [0_u8; 1];

// Important: This calls read until it returns Ok(0) to properly end the string value
while string_reader.read(&mut buf)? > 0 {
    println!("Read byte: {}", buf[0]);
}

// Drop the string reader to allow using the JSON reader again
drop(string_reader);

json_reader.end_array()?;
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

If the next value is not a JSON string value but is a value of a different type a ReaderError::UnexpectedValueType is returned. The peek method can be used to check the type if it is not known in advance.

§Reader errors

JSON syntax errors and invalid UTF-8 data which occurs while consuming the JSON string value with the reader are reported as std::io::Error for that reader.

The error behavior of the string reader differs from the guarantees made by Read:

  • if an error is returned there are no guarantees about if or how many data has been consumed from the underlying data source and been stored in the provided buf
  • if an error occurs, processing should be aborted, regardless of the kind of the error; trying to use the string reader or the underlying JSON reader afterwards will lead to unspecified behavior
§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn next_number_as_str(&mut self) -> Result<&str, ReaderError>

Consumes and returns the string representation of a JSON number value as str

This method is mainly intended for situations where parsing the number should be deferred to a later point, or the exact format of the JSON number should be preserved. However, this method nonetheless validates that the JSON number matches the format described by the JSON specification.

The method next_number can be used instead to parse the number directly in place.

The number value is returned as borrowed str. While that value is in scope, the Rust compiler might not permit using the JSON reader in any other way. If an owned String is needed, prefer next_number_as_string, that will most likely be more efficient than using this method to obtain a str and then converting that to an owned String.

§Examples
let mut json_reader = JsonStreamReader::new("12.0e5".as_bytes());
assert_eq!(json_reader.next_number_as_str()?, "12.0e5");
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

If the next value is not a JSON number value but is a value of a different type a ReaderError::UnexpectedValueType is returned. The peek method can be used to check the type if it is not known in advance.

If the number is too large or has too many decimal places a ReaderError::UnsupportedNumberValue is returned, depending on the reader settings.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn next_number_as_string(&mut self) -> Result<String, ReaderError>

Consumes and returns the string representation of a JSON number value as String

The string value is returned as owned String. If a borrowed str suffices for your use case, prefer next_number_as_str, that will most likely be more efficient.

See the documentation of next_number_as_str for a detailed description of the behavior of reading a number value as string.

source

fn next_bool(&mut self) -> Result<bool, ReaderError>

Consumes and returns a JSON boolean value

§Examples
let mut json_reader = JsonStreamReader::new("true".as_bytes());
assert_eq!(json_reader.next_bool()?, true);
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

If the next value is not a JSON boolean value but is a value of a different type a ReaderError::UnexpectedValueType is returned. The peek method can be used to check the type if it is not known in advance.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn next_null(&mut self) -> Result<(), ReaderError>

Consumes a JSON null value

This method does not return a value since there is nothing meaningful to return. Either the JSON value is a JSON null, or otherwise an error is returned because the value had a different type (see “Errors” section below).

§Examples
let mut json_reader = JsonStreamReader::new("null".as_bytes());
json_reader.next_null()?;
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

If the next value is not a JSON null value but is a value of a different type a ReaderError::UnexpectedValueType is returned. The peek method can be used to check the type if it is not known in advance.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn deserialize_next<'de, D: Deserialize<'de>>( &mut self ) -> Result<D, DeserializerError>

Available on crate feature serde only.

Deserializes a Serde Deserialize from the next value

This method is part of the optional Serde integration feature, see the serde module of this crate for more information.

If it is not possible to directly deserialize a value in place, instead of using this method a JsonReaderDeserializer can be constructed and deserialization can be performed using it later on. However, this should only be rarely necessary.

§Examples
// In this example JSON data comes from a string;
// normally it would come from a file or a network connection
let json = r#"{"outer": {"text": "some text", "number": 5}}"#;
let mut json_reader = JsonStreamReader::new(json.as_bytes());

// Skip outer data using the regular JsonReader methods
json_reader.seek_to(&json_path!["outer"])?;

#[derive(Deserialize, PartialEq, Debug)]
struct MyStruct {
    text: String,
    number: u64,
}

let value: MyStruct = json_reader.deserialize_next()?;

// Skip the remainder of the JSON document
json_reader.skip_to_top_level()?;

// Ensures that there is no trailing data
json_reader.consume_trailing_whitespace()?;

assert_eq!(
    value,
    MyStruct { text: "some text".to_owned(), number: 5 }
);
§Security

Since JSON data can have an arbitrary structure and can contain arbitrary data, care must be taken when processing untrusted data. See the documentation of JsonReaderDeserializer for security considerations.

§Errors

Errors can occur when either this JSON reader or the Deserialize encounters an error. In which situations this can happen depends on the Deserialize implementation.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn skip_name(&mut self) -> Result<(), ReaderError>

Skips the name of the next JSON object member

Afterwards one of the value reading methods such as next_number can be used to read the corresponding member value.

Skipping member names can be useful when the only the values of the JSON object members are relevant for the application processing the JSON document but the member names don’t matter.

Skipping member names with this method is usually more efficient than calling next_name but discarding its result. However, skip_name nonetheless also verifies that the skipped name has valid syntax.

§Examples
let mut json_reader = JsonStreamReader::new(r#"{"a": 1}"#.as_bytes());
json_reader.begin_object()?;

// Skip member name "a"
json_reader.skip_name()?;

assert_eq!(json_reader.next_number_as_str()?, "1");

To skip to a specific location in the JSON document the method seek_to can be used.

§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next object member a ReaderError::UnexpectedStructure is returned. has_next can be used to check if there are further members in the current JSON object.

§Panics

Panics when called on a JSON reader which currently does not expect a member name. This indicates incorrect usage by the user and is unrelated to the JSON data.

source

fn skip_value(&mut self) -> Result<(), ReaderError>

Skips the next value

This method can be used to skip top-level values, JSON array items and JSON object member values. To skip an object member name, the method skip_name has to be used.
Skipping a JSON array or object skips the complete value including all nested ones, if any.

Skipping values can be useful when parts of the processed JSON document are not relevant for the application processing it.

Skipping values with this method is usually more efficient than calling regular value reading methods (such as next_str()) but discarding their result. However, skip_value nonetheless also verifies that the skipped JSON data has valid syntax.

§Examples
let mut json_reader = JsonStreamReader::new(r#"{"a": [{}], "b": 1}"#.as_bytes());
json_reader.begin_object()?;

assert_eq!(json_reader.next_name()?, "a");

// Skip member value [{}]
json_reader.skip_value()?;

assert_eq!(json_reader.next_name()?, "b");

To skip to a specific location in the JSON document the method seek_to can be used.

§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

§Panics

Panics when called on a JSON reader which currently expects a member name (skip_name has to be used for that), or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn skip_to_top_level(&mut self) -> Result<(), ReaderError>

Skips the remaining elements of all currently enclosing JSON arrays and objects

Based on the current JSON reader position skips the remaining elements of all enclosing JSON arrays and objects (if any) until the top-level is reached. That is, for every array started with begin_array and for every object started with begin_object the remaining elements are skipped and the end of the array respectively object is consumed. During skipping, the syntax of the skipped values is validated. Calling this method has no effect when there is currently no enclosing JSON array or object.

This method is useful when a subsection of a JSON document has been consumed, for example with the help of seek_to, and afterwards either

  • the syntax of the remainder of the document should be validated and trailing data should be rejected, by calling consume_trailing_whitespace
  • or, multiple top-level values are enabled in the ReaderSettings and the next top-level value should be consumed
§Examples
let mut json_reader = JsonStreamReader::new(
    r#"{"bar": true, "foo": ["a", "b", "c"]}"#.as_bytes()
);
json_reader.seek_to(&json_path!["foo", 2])?;

// Consume the value to which the call seeked to
assert_eq!(json_reader.next_str()?, "c");

// Skip the remainder of the document
json_reader.skip_to_top_level()?;
// And verify that there is only optional whitespace, but no trailing data
json_reader.consume_trailing_whitespace()?;
§Errors

None, besides ReaderError::SyntaxError and ReaderError::IoError.

source

fn transfer_to<W: JsonWriter>( &mut self, json_writer: &mut W ) -> Result<(), TransferError>

Consumes the next value and writes it to the given JSON writer

This method consumes the next value and calls the corresponding methods on the JSON writer to emit the value again. Due to this, whitespace and comments, if enabled in the ReaderSettings, are not preserved. Instead the formatting of the output is dependent on the configuration of the JSON writer. Similarly the Unicode characters of member names and string values might be escaped differently. However, all these differences don’t have an effect on the JSON value. JSON readers will consider it to be equivalent. For JSON numbers the exact format is preserved.

This method is useful for extracting a subsection from a JSON document and / or for embedding it into another JSON document. Extraction can be done by using for example seek_to to position the reader before calling this method. Embedding can be done by already writing JSON data to the JSON writer before calling this method.

§Examples
let mut json_reader = JsonStreamReader::new(
    r#"{"bar": true, "foo": [1, 2]}"#.as_bytes()
);
json_reader.seek_to(&json_path!["foo"])?;

let mut writer = Vec::<u8>::new();
let mut json_writer = JsonStreamWriter::new(&mut writer);
json_writer.begin_object()?;
json_writer.name("embedded")?;

// Extract subsection from reader and embed it in the document created by the writer
json_reader.transfer_to(&mut json_writer)?;

json_writer.end_object()?;
json_writer.finish_document()?;

let json = String::from_utf8(writer)?;
assert_eq!(json, r#"{"embedded":[1,2]}"#);
§Errors

Errors are reported as TransferError which wraps either an error which occurred for this JSON reader or an error which occurred for the given JSON writer.

§Reader errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

§Writer errors

If writing the JSON value fails an IO error is returned.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings.

Panics when the given JSON writer currently expects a member name, or when it has already written a top-level value and multiple top-level values are not enabled in the WriterSettings.

These cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn consume_trailing_whitespace(self) -> Result<(), ReaderError>

Consumes trailing whitespace at the end of the top-level value

Additionally, if comments are allowed by the ReaderSettings also consumes trailing comments. If there is any trailing data a ReaderError::SyntaxError is returned.

This method can be useful to verify that a JSON document is wellformed and does not have any unexpected data at the end. This is not checked automatically by this JSON reader.

When multiple top-level values are allowed by the ReaderSettings but not all top-level values are relevant they can be skipped with of loop calling has_next and skip_value to allow calling consume_trailing_whitespace eventually:

// Skip all remaining top-level values
while json_reader.has_next()? {
    json_reader.skip_value()?;
}

// Verify that there is only optional whitespace, but no trailing data
json_reader.consume_trailing_whitespace()?;

Important: It is expected that there is always at least one top-level value in a JSON document, so calling this method without having consumed a value yet will panic, see “Panics” section below.

§Errors

(besides ReaderError::IoError)

If there is trailing data at the end of the top-level value a ReaderError::SyntaxError of kind SyntaxErrorKind::TrailingData is returned.

§Panics

Panics when called on a JSON reader which has not read any top-level yet, or when called while the top-level value has not been fully consumed yet. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn current_position(&self, include_path: bool) -> JsonReaderPosition

Gets the current position of this JSON reader within the JSON data

The position can be used to enhance custom errors when building a parser on top of this JSON reader. include_path determines whether the JSON path should be included, assuming the JSON reader implementation supports providing this information (if it doesn’t the path will be None regardless of include_path value). Including the JSON path can make the position information more useful for troubleshooting. However, if a caller frequently requests the position, for example to have it providently in case subsequent parsing fails, then it might improve performance to not include the path information.

Line and data position are only specified if has_next or peek have just been called, in which case their values point at the start of the next token. Otherwise their values can be anywhere between the previous token and the next token (if any).

The position information makes no guarantee about the amount of data (e.g. number of bytes) consumed from the underlying data source. JSON reader implementations might buffer data which has not been processed yet.

§Examples

Let’s assume an array of points encoded as JSON string in the format x|y should be parsed:

let mut json_reader = JsonStreamReader::new(
    r#"["1|2", "3|2", "8"]"#.as_bytes()
);
json_reader.begin_array()?;

while json_reader.has_next()? {
    let pos = json_reader.current_position(true);
    let encoded_point = json_reader.next_str()?;

    if let Some((x, y)) = encoded_point.split_once('|') {
        // ...
    } else {
        // Includes the JSON reader position for easier troubleshooting
        println!("Malformed point '{encoded_point}', at {pos}");
    }
}

Provided Methods§

source

fn next_number<T: FromStr>(&mut self) -> Result<Result<T, T::Err>, ReaderError>

Consumes and returns a JSON number value

The result is either the parsed number or the parse error. It might be necessary to help the Rust compiler a bit by explicitly specifying the number type in case it cannot be inferred automatically.

If parsing the number should be deferred to a later point or the exact format of the JSON number should be preserved, the method next_number_as_str can be used.

§Examples
let mut json_reader = JsonStreamReader::new("12".as_bytes());
assert_eq!(json_reader.next_number::<u32>()??, 12);
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If there is no next value a ReaderError::UnexpectedStructure is returned. The has_next method can be used to check if there is a next value.

If the next value is not a JSON number value but is a value of a different type a ReaderError::UnexpectedValueType is returned. The peek method can be used to check the type if it is not known in advance.

If the number is too large or has too many decimal places a ReaderError::UnsupportedNumberValue is returned, depending on the reader settings.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn seek_to(&mut self, rel_json_path: &JsonPath) -> Result<(), ReaderError>

Seeks to the specified location in the JSON document

Seeks to the specified relative JSON path in the JSON document by skipping all previous values. The JSON reader is expected to be positioned before the first value specified in the path. Once this method returns successfully the reader will be positioned before the last element specified by the path.

For example for the JSON path json_path!["foo", 2] it will start consuming a JSON object, skipping members until it finds one with name “foo”. Then it starts consuming the member value, expecting that it is a JSON array, until right before the array item with (starting at 0) index 2. If multiple members in a JSON object have the same name (for example {"a": 1, "a": 2}) this method will seek to the first occurrence.

Seeking to a specific location can be useful when parts of the processed JSON document are not relevant for the application processing it.

To continue reading at the original nesting level before seek_to had been called, use seek_back afterwards.

§Examples
let mut json_reader = JsonStreamReader::new(
    r#"{"bar": true, "foo": ["a", "b", "c"]}"#.as_bytes()
);
json_reader.seek_to(&json_path!["foo", 2])?;

// Can now consume the value to which the call seeked to
assert_eq!(json_reader.next_str()?, "c");
§Errors

(besides ReaderError::SyntaxError and ReaderError::IoError)

If the structure or the value types of the JSON document do not match the structure expected by the JSON path, either a ReaderError::UnexpectedStructure or a ReaderError::UnexpectedValueType is returned.

§Panics

Panics when called on a JSON reader which currently expects a member name, or when called after the top-level value has already been consumed and multiple top-level values are not enabled in the ReaderSettings. Both cases indicate incorrect usage by the user and are unrelated to the JSON data.

source

fn seek_back(&mut self, rel_json_path: &JsonPath) -> Result<(), ReaderError>

Opposite of seek_to

This is the opposite of the seek_to method; it goes through the path in reverse order skipping remaining JSON array items and object members and closing arrays and objects. Therefore once this method returns the reader is at the same nesting level it was before seek_to had been called and allows continuing reading values there.

For directly getting to the top-level regardless of the current position of the JSON reader, prefer skip_to_top_level instead.

The correct usage looks like this:

  1. Call seek_to with path
  2. Read one or more values
  3. Call seek_back with the same path

Using this method in a different way can lead to errors and panics. In particular it is important that for step 2:

  • the value and all nested values (if any) are fully consumed; any additional JSON arrays and objects which are started must be closed again
  • no enclosing JSON arrays or objects must be closed
  • if the path points to the member of a JSON object, then for every additionally read member name of that object the corresponding member value must be consumed as well
§Examples
let mut json_reader = JsonStreamReader::new(
    r#"[{"a": {"b": "first"}}, {"a": {"b": "second"}}]"#.as_bytes()
);
let mut values = Vec::<String>::new();

json_reader.begin_array()?;
while json_reader.has_next()? {
    let path = json_path!["a", "b"];
    json_reader.seek_to(&path)?;

    // Read the value to which the call seeked to
    let value = json_reader.next_string()?;
    values.push(value);

    // Go back to original location to continue reading there
    json_reader.seek_back(&path)?;
}
json_reader.end_array()?;

assert_eq!(values, vec!["first", "second"]);
§Panics

Panics may occur if not used according to the correct usage described above.

Object Safety§

This trait is not object safe.

Implementors§