From 53b7a3ca7f717c344773360d5c71320650b896f1 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Fri, 20 Sep 2024 13:22:44 +0800 Subject: [PATCH] feat: support `from_reader` (#113) --- examples/serde.rs | 11 +++++++++++ examples/testdata/person.json | 5 +++++ src/error.rs | 1 - src/lib.rs | 6 +++--- src/serde/de.rs | 13 +++++++++++++ src/serde/mod.rs | 4 +++- 6 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 examples/testdata/person.json 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 17d3897..70cbcfb 100644 --- a/src/error.rs +++ b/src/error.rs @@ -164,7 +164,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 8a2e738..0f02986 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,9 +41,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 5d76aaa..e0a4ce1 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -1370,3 +1370,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: std::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 7dcda6c..7154452 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::{