Remove deserialization from Iterator<Item = io::Result<u8>>

Use `from_reader` instead.
This commit is contained in:
David Tolnay
2017-04-19 18:51:12 -07:00
parent f61d72de7e
commit ac8b4fcb70
7 changed files with 26 additions and 200 deletions

View File

@@ -75,8 +75,7 @@ enum Value {
A string of JSON data can be parsed into a `serde_json::Value` by the
[`serde_json::from_str`][from_str] function. There is also
[`from_slice`][from_slice] for parsing from a byte slice &[u8],
[`from_iter`][from_iter] for parsing from an iterator of bytes, and
[`from_slice`][from_slice] for parsing from a byte slice &[u8] and
[`from_reader`][from_reader] for parsing from any `io::Read` like a File or
a TCP stream.
@@ -323,7 +322,6 @@ be dual licensed as above, without any additional terms or conditions.
[value]: https://docs.serde.rs/serde_json/value/enum.Value.html
[from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
[from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html
[from_iter]: https://docs.serde.rs/serde_json/de/fn.from_iter.html
[from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html
[to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html
[to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html

View File

@@ -18,7 +18,7 @@ use super::error::{Error, ErrorCode, Result};
use read::{self, Reference};
pub use read::{Read, IoRead, IteratorRead, SliceRead, StrRead};
pub use read::{Read, IoRead, SliceRead, StrRead};
//////////////////////////////////////////////////////////////////////////////
@@ -40,7 +40,6 @@ where
///
/// - Deserializer::from_str
/// - Deserializer::from_bytes
/// - Deserializer::from_iter
/// - Deserializer::from_reader
pub fn new(read: R) -> Self {
Deserializer {
@@ -51,16 +50,6 @@ where
}
}
impl<I> Deserializer<read::IteratorRead<I>>
where
I: Iterator<Item = io::Result<u8>>,
{
/// Creates a JSON deserializer from a `std::iter::Iterator`.
pub fn from_iter(iter: I) -> Self {
Deserializer::new(read::IteratorRead::new(iter))
}
}
impl<R> Deserializer<read::IoRead<R>>
where
R: io::Read,
@@ -1029,7 +1018,6 @@ where
///
/// - Deserializer::from_str(...).into_iter()
/// - Deserializer::from_bytes(...).into_iter()
/// - Deserializer::from_iter(...).into_iter()
/// - Deserializer::from_reader(...).into_iter()
pub fn new(read: R) -> Self {
let offset = read.byte_offset();
@@ -1122,23 +1110,6 @@ where
Ok(value)
}
/// Deserialize an instance of type `T` from an iterator over bytes of JSON.
///
/// This conversion can fail if the structure of the Value does not match the
/// structure expected by `T`, for example if `T` is a struct type but the Value
/// contains something other than a JSON map. It can also fail if the structure
/// is correct but `T`'s implementation of `Deserialize` decides that something
/// is wrong with the data, for example required struct fields are missing from
/// the JSON map or some number is too big to fit in the expected primitive
/// type.
pub fn from_iter<I, T>(iter: I) -> Result<T>
where
I: Iterator<Item = io::Result<u8>>,
T: de::DeserializeOwned,
{
from_trait(read::IteratorRead::new(iter))
}
/// Deserialize an instance of type `T` from an IO stream of JSON.
///
/// This conversion can fail if the structure of the Value does not match the
@@ -1153,7 +1124,7 @@ where
R: io::Read,
T: de::DeserializeOwned,
{
from_iter(rdr.bytes())
from_trait(read::IoRead::new(rdr))
}
/// Deserialize an instance of type `T` from bytes of JSON text.

View File

@@ -64,8 +64,7 @@
//!
//! A string of JSON data can be parsed into a `serde_json::Value` by the
//! [`serde_json::from_str`][from_str] function. There is also
//! [`from_slice`][from_slice] for parsing from a byte slice &[u8],
//! [`from_iter`][from_iter] for parsing from an iterator of bytes, and
//! [`from_slice`][from_slice] for parsing from a byte slice &[u8] and
//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or
//! a TCP stream.
//!
@@ -287,7 +286,6 @@
//! [value]: https://docs.serde.rs/serde_json/value/enum.Value.html
//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html
//! [from_iter]: https://docs.serde.rs/serde_json/de/fn.from_iter.html
//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html
//! [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html
//! [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html
@@ -300,7 +298,7 @@
#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "cargo-clippy", allow(
// Deserializer::from_str, from_iter, into_iter
// Deserializer::from_str, into_iter
should_implement_trait,
// integer and float ser/de requires these sorts of casts
cast_possible_truncation,
@@ -330,7 +328,7 @@ extern crate dtoa;
extern crate linked_hash_map;
#[doc(inline)]
pub use self::de::{Deserializer, StreamDeserializer, from_iter, from_reader, from_slice, from_str};
pub use self::de::{Deserializer, StreamDeserializer, from_reader, from_slice, from_str};
#[doc(inline)]
pub use self::error::{Error, Result};
#[doc(inline)]

View File

@@ -82,22 +82,14 @@ pub enum Reference<'b, 'c, T: ?Sized + 'static> {
Copied(&'c T),
}
/// JSON input source that reads from an iterator of bytes.
pub struct IteratorRead<Iter>
where
Iter: Iterator<Item = io::Result<u8>>,
{
iter: LineColIterator<Iter>,
/// Temporary storage of peeked byte.
ch: Option<u8>,
}
/// JSON input source that reads from a std::io input stream.
pub struct IoRead<R>
where
R: io::Read,
{
delegate: IteratorRead<io::Bytes<R>>,
iter: LineColIterator<io::Bytes<R>>,
/// Temporary storage of peeked byte.
ch: Option<u8>,
}
/// JSON input source that reads from a slice of bytes.
@@ -124,28 +116,28 @@ mod private {
//////////////////////////////////////////////////////////////////////////////
impl<Iter> IteratorRead<Iter>
impl<R> IoRead<R>
where
Iter: Iterator<Item = io::Result<u8>>,
R: io::Read,
{
/// Create a JSON input source to read from an iterator of bytes.
pub fn new(iter: Iter) -> Self {
IteratorRead {
iter: LineColIterator::new(iter),
/// Create a JSON input source to read from a std::io input stream.
pub fn new(reader: R) -> Self {
IoRead {
iter: LineColIterator::new(reader.bytes()),
ch: None,
}
}
}
impl<Iter> private::Sealed for IteratorRead<Iter>
impl<R> private::Sealed for IoRead<R>
where
Iter: Iterator<Item = io::Result<u8>>,
R: io::Read,
{
}
impl<Iter> IteratorRead<Iter>
impl<R> IoRead<R>
where
Iter: Iterator<Item = io::Result<u8>>,
R: io::Read,
{
fn parse_str_bytes<'s, T, F>(
&'s mut self,
@@ -181,9 +173,9 @@ where
}
}
impl<'de, Iter> Read<'de> for IteratorRead<Iter>
impl<'de, R> Read<'de> for IoRead<R>
where
Iter: Iterator<Item = io::Result<u8>>,
R: io::Read,
{
#[inline]
fn next(&mut self) -> io::Result<Option<u8>> {
@@ -257,72 +249,6 @@ where
//////////////////////////////////////////////////////////////////////////////
impl<R> IoRead<R>
where
R: io::Read,
{
/// Create a JSON input source to read from a std::io input stream.
pub fn new(reader: R) -> Self {
IoRead { delegate: IteratorRead::new(reader.bytes()) }
}
}
impl<R> private::Sealed for IoRead<R>
where
R: io::Read,
{
}
impl<'de, R> Read<'de> for IoRead<R>
where
R: io::Read,
{
#[inline]
fn next(&mut self) -> io::Result<Option<u8>> {
self.delegate.next()
}
#[inline]
fn peek(&mut self) -> io::Result<Option<u8>> {
self.delegate.peek()
}
#[inline]
fn discard(&mut self) {
self.delegate.discard();
}
#[inline]
fn position(&self) -> Position {
self.delegate.position()
}
#[inline]
fn peek_position(&self) -> Position {
self.delegate.peek_position()
}
#[inline]
fn byte_offset(&self) -> usize {
self.delegate.byte_offset()
}
#[inline]
fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>> {
self.delegate.parse_str(scratch)
}
#[inline]
fn parse_str_raw<'s>(
&'s mut self,
scratch: &'s mut Vec<u8>,
) -> Result<Reference<'de, 's, [u8]>> {
self.delegate.parse_str_raw(scratch)
}
}
//////////////////////////////////////////////////////////////////////////////
impl<'a> SliceRead<'a> {
/// Create a JSON input source to read from a slice of bytes.
pub fn new(slice: &'a [u8]) -> Self {
@@ -348,9 +274,9 @@ impl<'a> SliceRead<'a> {
pos
}
/// The big optimization here over IteratorRead is that if the string
/// contains no backslash escape sequences, the returned &str is a slice of
/// the raw JSON data so we avoid copying into the scratch space.
/// The big optimization here over IoRead is that if the string contains no
/// backslash escape sequences, the returned &str is a slice of the raw JSON
/// data so we avoid copying into the scratch space.
fn parse_str_bytes<'s, T: ?Sized, F>(
&'s mut self,
scratch: &'s mut Vec<u8>,

View File

@@ -68,8 +68,7 @@
//!
//! A string of JSON data can be parsed into a `serde_json::Value` by the
//! [`serde_json::from_str`][from_str] function. There is also
//! [`from_slice`][from_slice] for parsing from a byte slice &[u8],
//! [`from_iter`][from_iter] for parsing from an iterator of bytes, and
//! [`from_slice`][from_slice] for parsing from a byte slice &[u8] and
//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or
//! a TCP stream.
//!
@@ -106,7 +105,6 @@
//! [macro]: https://docs.serde.rs/serde_json/macro.json.html
//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html
//! [from_iter]: https://docs.serde.rs/serde_json/de/fn.from_iter.html
//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html
use std::fmt;

View File

@@ -29,12 +29,6 @@ macro_rules! test_stream {
assert_eq!($stream.byte_offset(), 0);
$test
}
{
let de = Deserializer::from_iter($data.bytes().map(Ok));
let mut $stream = de.into_iter::<$ty>();
assert_eq!($stream.byte_offset(), 0);
$test
}
{
let mut bytes = $data.as_bytes();
let de = Deserializer::from_reader(&mut bytes);

View File

@@ -39,7 +39,7 @@ use serde::ser::{self, Serialize, Serializer};
use serde_bytes::{ByteBuf, Bytes};
use serde_json::{Deserializer, Value, from_iter, from_reader, from_slice, from_str, from_value,
use serde_json::{Deserializer, Value, from_reader, from_slice, from_str, from_value,
to_string, to_string_pretty, to_value, to_vec, to_writer};
macro_rules! treemap {
@@ -606,9 +606,6 @@ where
let v: T = from_slice(s.as_bytes()).unwrap();
assert_eq!(v, value.clone());
let v: T = from_iter(s.bytes().map(Ok)).unwrap();
assert_eq!(v, value.clone());
// Make sure we can deserialize into a `Value`.
let json_value: Value = from_str(s).unwrap();
assert_eq!(json_value, to_value(&value).unwrap());
@@ -639,9 +636,6 @@ where
let v: T = from_slice(s.as_bytes()).unwrap();
assert_eq!(v, value.clone());
let v: T = from_iter(s.bytes().map(Ok)).unwrap();
assert_eq!(v, value.clone());
}
}
@@ -659,7 +653,6 @@ where
for &(s, err) in errors {
test_parse_err!(from_str::<T>(s) => err);
test_parse_err!(from_slice::<T>(s.as_bytes()) => err);
test_parse_err!(from_iter::<_, T>(s.bytes().map(Ok)) => err);
}
}
@@ -669,7 +662,6 @@ where
{
for &(s, err) in errors {
test_parse_err!(from_slice::<T>(s) => err);
test_parse_err!(from_iter::<_, T>(s.iter().cloned().map(Ok)) => err);
}
}
@@ -1694,57 +1686,6 @@ fn test_allow_ser_integers_as_map_keys() {
assert_eq!(to_string(&map).unwrap(), r#"{"-2":8,"-1":6,"1":2,"2":4}"#);
}
#[test]
fn test_from_iter_unfused() {
// Test that iterator isn't called after EOF.
use std;
struct Source<I: Iterator<Item = u8>> {
iter: I,
finished: bool,
}
impl<I: Iterator<Item = u8>> Iterator for Source<I> {
type Item = std::io::Result<u8>;
fn next(&mut self) -> Option<Self::Item> {
assert!(!self.finished, "next() called after iterator EOF");
match self.iter.next() {
Some(b) => Some(Ok(b)),
None => {
self.finished = true;
None
}
}
}
}
#[derive(Deserialize)]
struct Message {
key: u32,
}
let msg: Message = from_iter(
Source {
iter: b"{\"key\": 1337}".iter().cloned(),
finished: false,
},
)
.unwrap();
assert_eq!(msg.key, 1337);
let msg: Message = from_iter(
Source {
iter: b"{\"key\": 1337} \t\t ".iter().cloned(),
finished: false,
},
)
.unwrap();
assert_eq!(msg.key, 1337);
}
#[test]
fn test_json_macro() {
// This is tricky because the <...> is not a single TT and the comma inside