diff --git a/serde2/src/de.rs b/serde2/src/de.rs index 4375a00b..99c93dd6 100644 --- a/serde2/src/de.rs +++ b/serde2/src/de.rs @@ -1,7 +1,9 @@ +/* use std::collections::{HashMap, BTreeMap}; use std::collections::hash_map::Hasher; use std::hash::Hash; use std::num::FromPrimitive; +*/ /////////////////////////////////////////////////////////////////////////////// @@ -11,19 +13,18 @@ pub trait Error { fn end_of_stream_error() -> Self; } -pub trait Deserialize { - type Visitor: Visitor; - - fn deserialize(state: &mut S) -> Result; +pub trait Deserialize { + fn deserialize< + S: Deserializer, + >(state: &mut S) -> Result; } pub trait Deserializer { type Error: Error; fn visit< - R, - V: Visitor, - >(&mut self, visitor: &mut V) -> Result; + V: Visitor, + >(&mut self, visitor: &mut V) -> Result; /* fn visit_option< @@ -35,8 +36,12 @@ pub trait Deserializer { */ } -pub trait Visitor { - fn visit_null(&mut self) -> Result { +pub trait Visitor { + type Value; + + fn visit_unit< + E: Error, + >(&mut self) -> Result { Err(Error::syntax_error()) } @@ -106,13 +111,15 @@ pub trait Visitor { >(&mut self, _visitor: V) -> Result { Err(Error::syntax_error()) } + */ fn visit_seq< - V: SeqVisitor, - >(&mut self, _visitor: V) -> Result { + V: SeqVisitor, + >(&mut self, _visitor: V) -> Result { Err(Error::syntax_error()) } + /* fn visit_map< V: MapVisitor, >(&mut self, _visitor: V) -> Result { @@ -127,13 +134,16 @@ pub trait OptionVisitor { T: Deserialize, >(&mut self) -> Result, E>; } +*/ + +pub trait SeqVisitor { + type Error: Error; -pub trait SeqVisitor { fn visit< - T: Deserialize, - >(&mut self) -> Result, E>; + T: Deserialize, + >(&mut self) -> Result, Self::Error>; - fn end(&mut self) -> Result<(), E>; + fn end(&mut self) -> Result<(), Self::Error>; #[inline] fn size_hint(&self) -> (uint, Option) { @@ -141,6 +151,7 @@ pub trait SeqVisitor { } } +/* pub trait MapVisitor { fn visit< K: Deserialize, @@ -176,10 +187,12 @@ pub trait MapVisitor { struct UnitVisitor; -impl< - S: Deserializer, -> Visitor for UnitVisitor { - fn visit_null(&mut self) -> Result<(), S::Error> { +impl Visitor for UnitVisitor { + type Value = (); + + fn visit_unit< + E: Error, + >(&mut self) -> Result<(), E> { Ok(()) } @@ -193,12 +206,10 @@ impl< */ } -impl< - S: Deserializer, -> Deserialize for () { - type Visitor = UnitVisitor; - - fn deserialize(state: &mut S) -> Result<(), S::Error> { +impl Deserialize for () { + fn deserialize< + S: Deserializer, + >(state: &mut S) -> Result<(), S::Error> { state.visit(&mut UnitVisitor) } } @@ -349,45 +360,36 @@ impl< } /////////////////////////////////////////////////////////////////////////////// +*/ -impl< - T: Deserialize, - S: Deserializer, - E: Error, -> Deserialize for Vec { - fn deserialize(state: &mut S) -> Result, E> { - struct Visitor; +struct VecVisitor; - impl< - T: Deserialize, - S: Deserializer, - E: Error, - > self::Visitor, E> for Visitor { - fn visit_seq< - V: SeqVisitor, - >(&mut self, mut visitor: V) -> Result, E> { - let (len, _) = visitor.size_hint(); - let mut values = Vec::with_capacity(len); +impl Visitor for VecVisitor { + type Value = Vec; - loop { - match try!(visitor.visit()) { - Some(value) => { - values.push(value); - } - None => { - break; - } - } - } + fn visit_seq< + V: SeqVisitor, + >(&mut self, mut visitor: V) -> Result, V::Error> { + let (len, _) = visitor.size_hint(); + let mut values = Vec::with_capacity(len); - Ok(values) - } + while let Some(value) = try!(visitor.visit()) { + values.push(value); } - state.visit(&mut Visitor) + Ok(values) } } +impl Deserialize for Vec { + fn deserialize< + S: Deserializer, + >(state: &mut S) -> Result, S::Error> { + state.visit(&mut VecVisitor) + } +} + +/* /////////////////////////////////////////////////////////////////////////////// macro_rules! peel { @@ -521,3 +523,142 @@ impl< } } */ + +#[cfg(test)] +mod tests { + use super::{Deserialize, Deserializer, Visitor}; + use std::vec; + + enum Token { + Unit, + SeqStart(uint), + SeqSep, + SeqEnd, + } + + struct TokenDeserializer { + tokens: vec::IntoIter, + } + + impl TokenDeserializer { + fn new(tokens: Vec) -> TokenDeserializer { + TokenDeserializer { + tokens: tokens.into_iter(), + } + } + } + + #[derive(Copy, PartialEq, Show)] + enum Error { + SyntaxError, + EndOfStreamError, + } + + impl super::Error for Error { + fn syntax_error() -> Error { Error::SyntaxError } + + fn end_of_stream_error() -> Error { Error::EndOfStreamError } + } + + impl Deserializer for TokenDeserializer { + type Error = Error; + + fn visit< + V: Visitor, + >(&mut self, visitor: &mut V) -> Result { + match self.tokens.next() { + Some(Token::Unit) => visitor.visit_unit(), + Some(Token::SeqStart(len)) => { + visitor.visit_seq(TokenDeserializerSeqVisitor { + de: self, + len: len, + }) + } + Some(Token::SeqSep) | Some(Token::SeqEnd) => { + Err(Error::SyntaxError) + } + None => Err(Error::EndOfStreamError), + } + } + } + + struct TokenDeserializerSeqVisitor<'a> { + de: &'a mut TokenDeserializer, + len: uint, + } + + impl<'a> super::SeqVisitor for TokenDeserializerSeqVisitor<'a> { + type Error = Error; + + fn visit< + T: Deserialize, + >(&mut self) -> Result, Error> { + match self.de.tokens.next() { + Some(Token::SeqSep) => { + self.len -= 1; + Ok(Some(try!(Deserialize::deserialize(self.de)))) + } + Some(Token::SeqEnd) => Ok(None), + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStreamError), + } + } + + fn end(&mut self) -> Result<(), Error> { + match self.de.tokens.next() { + Some(Token::SeqEnd) => Ok(()), + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStreamError), + } + } + + fn size_hint(&self) -> (uint, Option) { + (self.len, Some(self.len)) + } + } + + macro_rules! declare_test { + ($name:ident { $($value:expr => $tokens:expr,)+ }) => { + #[test] + fn $name() { + $( + let mut de = TokenDeserializer::new($tokens); + let value: Result<_, Error> = Deserialize::deserialize(&mut de); + assert_eq!(value, Ok($value)); + )+ + } + } + } + + macro_rules! declare_tests { + ($($name:ident { $($value:expr => $tokens:expr,)+ })+) => { + $( + declare_test!($name { $($value => $tokens,)+ }); + )+ + } + } + + declare_tests! { + test_unit { + () => vec![Token::Unit], + } + test_vec { + Vec::<()>::new() => vec![ + Token::SeqStart(0), + Token::SeqEnd, + ], + vec![(), (), ()] => vec![ + Token::SeqStart(3), + Token::SeqSep, + Token::Unit, + + Token::SeqSep, + Token::Unit, + + Token::SeqSep, + Token::Unit, + Token::SeqEnd, + ], + } + } +} diff --git a/serde2/src/lib.rs b/serde2/src/lib.rs index e0649878..d9c07447 100644 --- a/serde2/src/lib.rs +++ b/serde2/src/lib.rs @@ -5,5 +5,5 @@ extern crate unicode; //pub use ser::GatherTokens; pub mod ser; -//pub mod de; +pub mod de; //pub mod json; diff --git a/serde2/src/ser.rs b/serde2/src/ser.rs index 4608a418..640d6385 100644 --- a/serde2/src/ser.rs +++ b/serde2/src/ser.rs @@ -1047,6 +1047,19 @@ mod tests { } } + macro_rules! btreemap { + () => { + BTreeMap::new() + }; + ($($key:expr => $value:expr),+) => { + { + let mut map = BTreeMap::new(); + $(map.insert($key, $value);)+ + map + } + } + } + macro_rules! declare_test { ($name:ident { $($value:expr => $tokens:expr,)+ }) => { #[test] @@ -1070,29 +1083,11 @@ mod tests { } } - macro_rules! btreemap { - () => { - BTreeMap::new() - }; - ($($key:expr => $value:expr),+) => { - { - let mut map = BTreeMap::new(); - $(map.insert($key, $value);)+ - map - } - } - } - macro_rules! declare_tests { ($($name:ident { $($value:expr => $tokens:expr,)+ })+) => { $( declare_test!($name { $($value => $tokens,)+ }); )+ - }; - ($($name:ident { $($value:expr: $ty:ty => $tokens:expr,)+ })+) => { - $( - declare_test!($($name { $($value:$ty => $tokens,)+ })+); - )+ } }