[−][src]Struct nop_json::Reader
Implementations
impl<T> Reader<T> where
T: Iterator<Item = u8>,
[src]
T: Iterator<Item = u8>,
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]
U: TryFromJson,
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]
U: TryFromJson,
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]
U: TryFromJson,
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:
00 - 1F
- we can encode with the\u00xx
encoding - this is the only option.20 - 7F
except"
and\
- we can leave intact - they are valid utf-8 JSON, or optionally we can encode them with\u00xx
."
and\
- escape with a slash.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]
U: Write,
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]
F: FnMut(&mut Self, String) -> Result<()>,
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]
F: FnMut(&mut Self) -> Result<()>,
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]
F: FnMut(&mut Self) -> Result<()>,
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]
T: RefUnwindSafe,
impl<T> Send for Reader<T> where
T: Send,
[src]
T: Send,
impl<T> Sync for Reader<T> where
T: Sync,
[src]
T: Sync,
impl<T> Unpin for Reader<T> where
T: Unpin,
[src]
T: Unpin,
impl<T> UnwindSafe for Reader<T> where
T: UnwindSafe,
[src]
T: UnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,