diff --git a/examples/serde.rs b/examples/serde.rs index cbe0181..9853d23 100644 --- a/examples/serde.rs +++ b/examples/serde.rs @@ -1,3 +1,5 @@ +use std::fs::File; + use sonic_rs::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] @@ -8,6 +10,7 @@ struct Person { } fn main() { + // parse a string let data = r#"{ "name": "Xiaoming", "age": 18, @@ -20,4 +23,12 @@ fn main() { assert_eq!(p.name, "Xiaoming"); let out = sonic_rs::to_string_pretty(&p).unwrap(); assert_eq!(out, data); + + // parse a file reader + let p: Person = + sonic_rs::from_reader(File::open("examples/testdata/person.json").unwrap()).unwrap(); + assert_eq!(p.age, 18); + assert_eq!(p.name, "Xiaoming"); + let out = sonic_rs::to_string_pretty(&p).unwrap(); + assert_eq!(out, data); } diff --git a/examples/testdata/person.json b/examples/testdata/person.json new file mode 100644 index 0000000..c6b6a44 --- /dev/null +++ b/examples/testdata/person.json @@ -0,0 +1,5 @@ +{ + "name": "Xiaoming", + "age": 18, + "phones": ["+123456"] +} diff --git a/src/error.rs b/src/error.rs index 23eee6d..2b718f0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -163,7 +163,6 @@ impl From for std::io::Error { pub enum Category { /// The error was caused by a failure to read or write bytes on an I/O /// stream. - /// TODO: support stream reader in the future Io, /// The error was caused by input that was not syntactically valid JSON. diff --git a/src/lib.rs b/src/lib.rs index d064b03..2c82fc9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,9 +40,9 @@ pub use crate::lazyvalue::{ pub use crate::pointer::{JsonPointer, PointerNode, PointerTree}; #[doc(inline)] pub use crate::serde::{ - from_slice, from_slice_unchecked, from_str, to_string, to_string_pretty, to_vec, to_vec_pretty, - to_writer, to_writer_pretty, Deserializer, JsonNumberTrait, Number, RawNumber, Serializer, - StreamDeserializer, + from_reader, from_slice, from_slice_unchecked, from_str, to_string, to_string_pretty, to_vec, + to_vec_pretty, to_writer, to_writer_pretty, Deserializer, JsonNumberTrait, Number, RawNumber, + Serializer, StreamDeserializer, }; #[doc(inline)] pub use crate::value::{ diff --git a/src/serde/de.rs b/src/serde/de.rs index 59e1c9a..69a1a50 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -1,7 +1,7 @@ //! Deserialize JSON data to a Rust data structure. // The code is cloned from [serde_json](https://github.com/serde-rs/json) and modified necessary parts. -use std::{marker::PhantomData, mem::ManuallyDrop, ptr::slice_from_raw_parts}; +use std::{io, marker::PhantomData, mem::ManuallyDrop, ptr::slice_from_raw_parts}; use serde::{ de::{self, Expected, Unexpected}, @@ -1303,3 +1303,16 @@ where { from_trait(Read::new(s.as_bytes(), false)) } + +/// Deserialize an instance of type `T` from a Reader +pub fn from_reader(mut reader: R) -> Result +where + R: io::Read, + T: de::DeserializeOwned, +{ + let mut data = Vec::new(); + if let Err(e) = reader.read_to_end(&mut data) { + return Err(Error::io(e)); + }; + from_slice(data.as_slice()) +} diff --git a/src/serde/mod.rs b/src/serde/mod.rs index 7448b18..027084d 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -7,7 +7,9 @@ pub(crate) mod ser; pub(crate) use self::de::tri; pub use self::{ - de::{from_slice, from_slice_unchecked, from_str, Deserializer, StreamDeserializer}, + de::{ + from_reader, from_slice, from_slice_unchecked, from_str, Deserializer, StreamDeserializer, + }, number::{JsonNumberTrait, Number}, rawnumber::RawNumber, ser::{