Skip to content

Commit

Permalink
Merge pull request #250 from serde-rs/stream
Browse files Browse the repository at this point in the history
Expose serde_json::de::Read to use in where clauses
  • Loading branch information
dtolnay authored Feb 11, 2017
2 parents 426255b + 7a6e4bf commit d55dff7
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
28 changes: 23 additions & 5 deletions json/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use serde::de::{self, Unexpected};

use super::error::{Error, ErrorCode, Result};

use read::{self, Read};
use read;

pub use read::Read;

//////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -873,10 +875,26 @@ impl<'a, R: Read + 'a> de::VariantVisitor for UnitVariantVisitor<'a, R> {
//////////////////////////////////////////////////////////////////////////////

/// Iterator that deserializes a stream into multiple JSON values.
pub struct StreamDeserializer<R, T>
where R: Read,
T: de::Deserialize,
{
///
/// A stream deserializer can be create from any JSON deserializer using the
/// `Deserializer::into_iter` method.
///
/// ```rust
/// extern crate serde_json;
///
/// use serde_json::{Deserializer, Value};
///
/// fn main() {
/// let data = "1 2 {\"k\": 3}";
///
/// let stream = Deserializer::from_str(data).into_iter::<Value>();
///
/// for value in stream {
/// println!("{}", value.unwrap());
/// }
/// }
/// ```
pub struct StreamDeserializer<R, T> {
de: Deserializer<R>,
_marker: PhantomData<T>,
}
Expand Down
23 changes: 22 additions & 1 deletion json/src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ use super::error::{Error, ErrorCode, Result};
/// Trait used by the deserializer for iterating over input. This is manually
/// "specialized" for iterating over &[u8]. Once feature(specialization) is
/// stable we can use actual specialization.
pub trait Read {
///
/// This trait is sealed and cannot be implemented for types outside of
/// `serde_json`.
pub trait Read: private::Sealed {
#[doc(hidden)]
fn next(&mut self) -> io::Result<Option<u8>>;
#[doc(hidden)]
fn peek(&mut self) -> io::Result<Option<u8>>;

/// Only valid after a call to peek(). Discards the peeked byte.
#[doc(hidden)]
fn discard(&mut self);

/// Position of the most recent call to next().
Expand All @@ -21,6 +27,7 @@ pub trait Read {
/// actually peek() because we don't always know.
///
/// Only called in case of an error, so performance is not important.
#[doc(hidden)]
fn position(&self) -> Position;

/// Position of the most recent call to peek().
Expand All @@ -30,11 +37,13 @@ pub trait Read {
/// actually next() because we don't always know.
///
/// Only called in case of an error, so performance is not important.
#[doc(hidden)]
fn peek_position(&self) -> Position;

/// Assumes the previous byte was a quotation mark. Parses a JSON-escaped
/// string until the next quotation mark using the given scratch space if
/// necessary. The scratch space is initially empty.
#[doc(hidden)]
fn parse_str<'s>(
&'s mut self,
scratch: &'s mut Vec<u8>
Expand Down Expand Up @@ -68,6 +77,11 @@ pub struct StrRead<'a> {
delegate: SliceRead<'a>,
}

// Prevent users from implementing the Read trait.
mod private {
pub trait Sealed {}
}

//////////////////////////////////////////////////////////////////////////////

impl<Iter> IteratorRead<Iter>
Expand All @@ -81,6 +95,9 @@ impl<Iter> IteratorRead<Iter>
}
}

impl<Iter> private::Sealed for IteratorRead<Iter>
where Iter: Iterator<Item = io::Result<u8>> {}

impl<Iter> Read for IteratorRead<Iter>
where Iter: Iterator<Item = io::Result<u8>>,
{
Expand Down Expand Up @@ -242,6 +259,8 @@ impl<'a> SliceRead<'a> {
}
}

impl<'a> private::Sealed for SliceRead<'a> {}

impl<'a> Read for SliceRead<'a> {
#[inline]
fn next(&mut self) -> io::Result<Option<u8>> {
Expand Down Expand Up @@ -300,6 +319,8 @@ impl<'a> StrRead<'a> {
}
}

impl<'a> private::Sealed for StrRead<'a> {}

impl<'a> Read for StrRead<'a> {
#[inline]
fn next(&mut self) -> io::Result<Option<u8>> {
Expand Down

0 comments on commit d55dff7

Please # to comment.