diff --git a/serde2/src/bin.rs b/serde2/src/bin.rs index 14cc565d..b3cfb44f 100644 --- a/serde2/src/bin.rs +++ b/serde2/src/bin.rs @@ -1,7 +1,8 @@ extern crate serde2; -use std::string; +use std::collections::HashMap; use std::option; +use std::string; use serde2::de2; use serde2::de2::{Deserialize, Deserializer}; @@ -13,7 +14,7 @@ enum Token { String(string::String), Option(bool), SeqStart(uint), - //MapStart(uint), + MapStart(uint), End, } @@ -80,11 +81,9 @@ impl> Deserializer for MyDeserializer { Some(SeqStart(len)) => { visitor.visit_seq(self, MySeqVisitor { len: len }) } - /* Some(MapStart(len)) => { visitor.visit_map(self, MyMapVisitor { len: len }) } - */ Some(End) => { Err(self.syntax_error()) } @@ -186,15 +185,17 @@ impl< } } -/* struct MyMapVisitor { len: uint, } impl< Iter: Iterator, -> Visitor, ()> for MyMapVisitor { - fn next(&mut self, d: &mut MyDeserializer) -> Option> { +> de2::MapVisitor, Error> for MyMapVisitor { + fn next< + K: Deserialize, Error>, + V: Deserialize, Error>, + >(&mut self, d: &mut MyDeserializer) -> option::Option> { match d.peek() { Some(&End) => { d.next(); @@ -202,7 +203,18 @@ impl< } Some(_) => { self.len -= 1; - Some(d.visit_map_elt()) + + let key = match Deserialize::deserialize(d) { + Ok(key) => key, + Err(err) => { return Some(Err(err)); } + }; + + let value = match Deserialize::deserialize(d) { + Ok(value) => value, + Err(err) => { return Some(Err(err)); } + }; + + Some(Ok((key, value))) } None => { Some(Err(d.syntax_error())) @@ -210,11 +222,18 @@ impl< } } - fn size_hint(&self) -> (uint, Option) { + fn end(&mut self, d: &mut MyDeserializer) -> Result<(), Error> { + match d.next() { + Some(End) => Ok(()), + Some(_) => Err(d.syntax_error()), + None => Err(d.end_of_stream_error()), + } + } + + fn size_hint(&self, _d: &mut MyDeserializer) -> (uint, option::Option) { (self.len, Some(self.len)) } } -*/ /////////////////////////////////////////////////////////////////////////////// @@ -439,6 +458,21 @@ fn main() { let v: Result = Deserialize::deserialize(&mut state); println!("option value: {}", v); + //// + + let tokens = vec!( + MapStart(2), + String("a".to_string()), + Int(1), + String("b".to_string()), + Int(2), + End + ); + let mut state = MyDeserializer::new(tokens.into_iter()); + + let v: Result, Error> = Deserialize::deserialize(&mut state); + println!("{}", v); + /* //// @@ -452,22 +486,7 @@ fn main() { ); let mut state = MyDeserializer::new(tokens.into_iter()); - let v: Result, ()> = Deserialize::deserialize(&mut state); - println!("{}", v); - - //// - - let tokens = vec!( - MapStart(2), - String("a".to_string()), - Int(1), - String("b".to_string()), - Int(2), - End - ); - let mut state = MyDeserializer::new(tokens.into_iter()); - - let v: Result = Deserialize::deserialize(&mut state); + let v: Result = Deserialize::deserialize(&mut state); println!("{}", v); */ } diff --git a/serde2/src/de2.rs b/serde2/src/de2.rs index 90505a6a..ae010e69 100644 --- a/serde2/src/de2.rs +++ b/serde2/src/de2.rs @@ -1,5 +1,5 @@ -//use std::collections::{HashMap, TreeMap}; -//use std::hash::Hash; +use std::collections::{HashMap, TreeMap}; +use std::hash::Hash; /////////////////////////////////////////////////////////////////////////////// @@ -49,7 +49,13 @@ pub trait Visitor, R, E> { } fn visit_seq< - V: SeqVisitor + V: SeqVisitor, + >(&mut self, d: &mut D, _visitor: V) -> Result { + Err(d.syntax_error()) + } + + fn visit_map< + V: MapVisitor, >(&mut self, d: &mut D, _visitor: V) -> Result { Err(d.syntax_error()) } @@ -74,6 +80,20 @@ pub trait SeqVisitor { } } +pub trait MapVisitor { + fn next< + K: Deserialize, + V: Deserialize, + >(&mut self, d: &mut D) -> Option>; + + fn end(&mut self, d: &mut D) -> Result<(), E>; + + #[inline] + fn size_hint(&self, _d: &mut D) -> (uint, Option) { + (0, None) + } +} + /////////////////////////////////////////////////////////////////////////////// impl< @@ -257,7 +277,92 @@ impl< } } +/////////////////////////////////////////////////////////////////////////////// +impl< + K: Deserialize + Eq + Hash, + V: Deserialize, + D: Deserializer, + E, +> Deserialize for HashMap { + fn deserialize(d: &mut D) -> Result, E> { + struct Visitor; + + impl< + K: Deserialize + Eq + Hash, + V: Deserialize, + D: Deserializer, + E, + > self::Visitor, E> for Visitor { + fn visit_map< + Visitor: MapVisitor, + >(&mut self, d: &mut D, mut visitor: Visitor) -> Result, E> { + let (len, _) = visitor.size_hint(d); + let mut values = HashMap::with_capacity(len); + + loop { + match visitor.next(d) { + Some(Ok((key, value))) => { + values.insert(key, value); + } + Some(Err(err)) => { + return Err(err); + } + None => { + break; + } + } + } + + Ok(values) + } + } + + d.visit(&mut Visitor) + } +} + +impl< + K: Deserialize + Eq + Ord, + V: Deserialize, + D: Deserializer, + E, +> Deserialize for TreeMap { + fn deserialize(d: &mut D) -> Result, E> { + struct Visitor; + + impl< + K: Deserialize + Eq + Ord, + V: Deserialize, + D: Deserializer, + E, + > self::Visitor, E> for Visitor { + fn visit_map< + Visitor: MapVisitor, + >(&mut self, d: &mut D, mut visitor: Visitor) -> Result, E> { + let mut values = TreeMap::new(); + + loop { + match visitor.next(d) { + Some(Ok((key, value))) => { + values.insert(key, value); + } + Some(Err(err)) => { + return Err(err); + } + None => { + break; + } + } + } + + Ok(values) + } + } + + d.visit(&mut Visitor) + } +} /* trait Deserialize {