[][src]Struct nop_json::Reader

pub struct Reader<T> where
    T: Iterator<Item = u8>, 
{ /* fields omitted */ }

Implementations

impl<T> Reader<T> where
    T: Iterator<Item = u8>, 
[src]

pub fn new(iter: T) -> Reader<T>[src]

Construct new reader object, that can read values from a JSON stream, passing an object that implements Iterator<Item=u8>. This allows to use &str as data source like this:

let source = "\"Data\"";
let mut reader = Reader::new(source.bytes());

To use &[u8] do this:

let source: &[u8] = b"\"Data\"";
let mut reader = Reader::new(source.iter().map(|i| *i));

To use std::io::Read as source, you can convert it to Iterator<Item=u8> like this:

use std::io::Read;
use nop_json::Reader;
let source = std::io::stdin();
let source = source.lock(); // this implements std::io::Read
let mut reader = Reader::new(source.bytes().map(|b| b.unwrap()));

Though, this will panic on i/o error. Another technique is to use read_iter crate.

use read_iter::ReadIter;
use nop_json::Reader;
let mut source = ReadIter::new(std::io::stdin());
let mut reader = Reader::new(&mut source);
// ...
source.take_last_error().unwrap();

From file like this:

use std::fs::File;
use read_iter::ReadIter;
use nop_json::Reader;
let mut source = ReadIter::new(File::open("/tmp/test.json").unwrap());
let mut reader = Reader::new(&mut source);
// ...
source.take_last_error().unwrap();

pub fn unwrap(self) -> T[src]

Destroy this reader, unwrapping the underlying iterator that was passed to constructor when this object created.

pub fn read<U>(&mut self) -> Result<U> where
    U: TryFromJson
[src]

Read one JSON value from the stream.

The value will be converted to target variable type with TryFromJson trait. The conversion is inspired by Javascript values conversion. For example, a JSON string that represents a number (like "123.4e5") can be read to a numeric variable.

pub fn read_prop<U>(&mut self, prop: &'static str) -> Result<U> where
    U: TryFromJson
[src]

This method is intended for use in cases when you want to implement TryFromJson manually. Use it when you read an object with read_object() or read_object_use_buffer(). It works like read(), but uses provided static string, that must be the name of the object property taht you are reading, in error message.

pub fn read_index<U>(&mut self) -> Result<U> where
    U: TryFromJson
[src]

This method is intended for use in cases when you want to implement TryFromJson manually. Use it when you read an array with read_array(). It works like read(), but if error occures, the error message will contain index number in array. The index number is stored internally, and is incremented each time you call read_index() (read_array() resets it).

pub fn format_error(&self, msg: &str) -> Error[src]

Creates std::io::Error from given string. The error message will be prefixed with current path in objects/arrays tree. This path is built by read_prop() and read_index().

pub fn format_error_fmt(&self, args: Arguments<'_>) -> Error[src]

Like format_error(), but receives std::fmt::Arguments object. Create it with format_args!().

pub fn read_bytes(&mut self) -> Result<&[u8]>[src]

Reads a JSON string (numbers, booleans and null will be converted to string) to internal buffer, which is 128 bytes long. And return a reference to the read bytes. Long strings will be truncated.

pub fn read_blob(&mut self) -> Result<Vec<u8>>[src]

This function allows us to exploit standard JSON containers to pass binary data (BLOBs, binary large objects, or Vec<u8>). Does JSON standard strictly prohibit us to do so? Lets understand the principle behind this criminal operation.

Mr. JSON wants us to interchange only unicode strings. But he doesn't specify what unicode it must be: utf-8, utf-16, or other. What is invalid utf-8 can be valid utf-16, and what is invalid utf-16 can be valid something else. Furthermore, passing invalid strings is normal, it happens every day. The receiver of invalid string must reject it immediately, and not use it for his profit. This library obeys to this requirement, and invalid utf-8 (only this encoding is supported) will fail conversion from Vec<u8> to String. So reading an invalid utf-8 byte sequence to a String variable will really return error. But nop-json library can optionally return you the Vec<u8> and tell you to convert it to String by yourself. And you may decide not to do so, and get your hands on this useful byte sequence.

The trouble here is only with bytes in range 80 - FF. Here is how we can encode our binary object:

  1. 00 - 1F - we can encode with the \u00xx encoding - this is the only option.
  2. 20 - 7F except " and \ - we can leave intact - they are valid utf-8 JSON, or optionally we can encode them with \u00xx.
  3. " and \ - escape with a slash.
  4. 80 - FF - if we leave them as they are, this will make our string invalid utf-8 (but valid JSON container). Ask yourself can you live with this. Another option could be to encode these characters with \u00xx sequences, but \u0080 expands to 2-byte utf-8 character.
use nop_json::Reader;

let mut reader = Reader::new(b" \"\x80\x81\" ".iter().map(|i| *i));

let data = reader.read_blob().unwrap();
assert_eq!(data, b"\x80\x81");

pub fn pipe_blob<U>(&mut self, writer: &mut U) -> Result<()> where
    U: Write
[src]

Like read_blob(), but pipes the data to the provided writer.

pub fn read_object<F>(&mut self, mut on_value: F) -> Result<bool> where
    F: FnMut(&mut Self, String) -> Result<()>, 
[src]

This method is intended for use in cases when you want to implement TryFromJson manually. This method reads a JSON object from the stream.

First it reads starting { char from the stream. Then it reads a property name. Then for each property name read, it calls given callback function, assuming that from this function you will read the property value, with read_prop(). Reading the value with read() will also work (but in case of error, the error message will not contain path to the property where error occured).

Example:


let mut reader = Reader::new(r#" {"x": 10, "y": "the y"} "#.bytes());

let mut x: Option<i32> = None;
let mut y = String::new();

reader.read_object
(	|reader, prop|
	{	match prop.as_ref()
		{	"x" => x = reader.read_prop("x")?,
			"y" => y = reader.read_prop("y")?,
			_ => return Err(reader.format_error_fmt(format_args!("Invalid property: {}", prop)))
		}
		Ok(())
	}
)?;

assert_eq!(x, Some(10));
assert_eq!(y, "the y".to_string());

pub fn read_object_use_buffer<F>(&mut self, mut on_value: F) -> Result<bool> where
    F: FnMut(&mut Self) -> Result<()>, 
[src]

This method is intended for use in cases when you want to implement TryFromJson manually. This method reads a JSON object from the stream.

First it reads starting { char from the stream. Then it reads a property name, and stores it in internal buffer. You can get it with get_key(). The buffer is 128 bytes long, so if the property name is longer, it will be truncated. To avoid this limitation, use read_object(). Then for each property name read, it calls given callback function, assuming that from this function you will read the property value, with read_prop(). Reading the value with read() will also work (but in case of error, the error message will not contain path to the property where error occured).

Example:


let mut reader = Reader::new(r#" {"x": 10, "y": "the y"} "#.bytes());

let mut x: Option<i32> = None;
let mut y = String::new();

reader.read_object_use_buffer
(	|reader|
	{	match reader.get_key()
		{	b"x" => x = reader.read_prop("x")?,
			b"y" => y = reader.read_prop("y")?,
			_ => return Err(reader.format_error_fmt(format_args!("Invalid property: {}", String::from_utf8_lossy(reader.get_key()))))
		}
		Ok(())
	}
)?;

assert_eq!(x, Some(10));
assert_eq!(y, "the y".to_string());

pub fn get_key(&self) -> &[u8][src]

pub fn read_array<F>(&mut self, mut on_value: F) -> Result<bool> where
    F: FnMut(&mut Self) -> Result<()>, 
[src]

This method is intended for use in cases when you want to implement TryFromJson manually. This method reads a JSON array from the stream.

First it reads starting [ char from the stream. Then it calls given callback function as many times as needed to read each value till terminating ]. The callback function is assumed to call read_index() to read next array element.

Example:


let mut reader = Reader::new(r#" ["One", "Two", "Three"] "#.bytes());

let mut value: Vec<String> = Vec::new();

reader.read_array
(	|reader|
	{	value.push(reader.read_index()?);
		Ok(())
	}
)?;

assert_eq!(value, vec!["One".to_string(), "Two".to_string(), "Three".to_string()]);

Auto Trait Implementations

impl<T> RefUnwindSafe for Reader<T> where
    T: RefUnwindSafe
[src]

impl<T> Send for Reader<T> where
    T: Send
[src]

impl<T> Sync for Reader<T> where
    T: Sync
[src]

impl<T> Unpin for Reader<T> where
    T: Unpin
[src]

impl<T> UnwindSafe for Reader<T> where
    T: UnwindSafe
[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.