diff --git a/de.rs b/de.rs index cd17b1e3..dd53d380 100644 --- a/de.rs +++ b/de.rs @@ -28,6 +28,8 @@ pub enum Token { Option(bool), TupleStart(uint), + StructStart(&'static str), + StructField(&'static str), SeqStart(uint), MapStart(uint), @@ -160,6 +162,34 @@ pub trait Deserializer: Iterator> { } } + #[inline] + fn expect_struct_start(&mut self, name: &str) -> Result<(), E> { + match_token! { + StructStart(n) => { + if name == n { + Ok(()) + } else { + Err(self.syntax_error()) + } + } + } + } + + #[inline] + fn expect_struct_field< + T: Deserializable + >(&mut self, name: &str) -> Result { + match_token! { + StructField(n) => { + if name == n { + Deserializable::deserialize(self) + } else { + Err(self.syntax_error()) + } + } + } + } + #[inline] fn expect_collection< T: Deserializable, @@ -379,12 +409,50 @@ mod tests { use self::serialize::{Decoder, Decodable}; - use super::{Token, Null, Int, StrBuf}; - use super::{TupleStart, SeqStart, MapStart, Sep, End}; + use super::{Token, Null, Int, Uint, Str, StrBuf, Char, Option}; + use super::{TupleStart, StructStart, StructField, SeqStart, MapStart, Sep, End}; use super::{Deserializer, Deserializable}; ////////////////////////////////////////////////////////////////////////////// + #[deriving(Eq, Show)] + struct Inner { + a: (), + b: uint, + c: HashMap>, + } + + impl> Deserializable for Inner { + #[inline] + fn deserialize(d: &mut D) -> Result { + try!(d.expect_struct_start("Inner")); + let a = try!(d.expect_struct_field("a")); + let b = try!(d.expect_struct_field("b")); + let c = try!(d.expect_struct_field("c")); + try!(d.expect_end()); + Ok(Inner { a: a, b: b, c: c }) + } + } + + ////////////////////////////////////////////////////////////////////////////// + + #[deriving(Eq, Show)] + struct Outer { + inner: Vec, + } + + impl> Deserializable for Outer { + #[inline] + fn deserialize(d: &mut D) -> Result { + try!(d.expect_struct_start("Outer")); + let inner = try!(d.expect_struct_field("inner")); + try!(d.expect_end()); + Ok(Outer { inner: inner }) + } + } + + ////////////////////////////////////////////////////////////////////////////// + #[deriving(Show)] enum Error { EndOfStream, @@ -534,6 +602,8 @@ mod tests { } } + ////////////////////////////////////////////////////////////////////////////// + impl Decoder for IntsDecoder { // Primitive types: fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) } @@ -625,9 +695,21 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result = Deserializable::deserialize(&mut deserializer); + let value: int = Deserializable::deserialize(&mut deserializer).unwrap(); - assert_eq!(value.unwrap(), 5); + assert_eq!(value, 5); + } + + #[test] + fn test_tokens_str() { + let tokens = vec!( + Str("a"), + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: &'static str = Deserializable::deserialize(&mut deserializer).unwrap(); + + assert_eq!(value, "a"); } #[test] @@ -637,12 +719,11 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result = Deserializable::deserialize(&mut deserializer); + let value: StrBuf = Deserializable::deserialize(&mut deserializer).unwrap(); - assert_eq!(value.unwrap(), "a".to_strbuf()); + assert_eq!(value, "a".to_strbuf()); } - #[test] fn test_tokens_null() { let tokens = vec!( @@ -650,9 +731,9 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result<(), Error> = Deserializable::deserialize(&mut deserializer); + let value: () = Deserializable::deserialize(&mut deserializer).unwrap(); - assert_eq!(value.unwrap(), ()); + assert_eq!(value, ()); } #[test] @@ -663,9 +744,34 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result<(), Error> = Deserializable::deserialize(&mut deserializer); + let value: () = Deserializable::deserialize(&mut deserializer).unwrap(); - assert_eq!(value.unwrap(), ()); + assert_eq!(value, ()); + } + + #[test] + fn test_tokens_option_none() { + let tokens = vec!( + Option(false), + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Option = Deserializable::deserialize(&mut deserializer).unwrap(); + + assert_eq!(value, None); + } + + #[test] + fn test_tokens_option_some() { + let tokens = vec!( + Option(true), + Int(5), + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Option = Deserializable::deserialize(&mut deserializer).unwrap(); + + assert_eq!(value, Some(5)); } #[test] @@ -681,9 +787,9 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result<(int, StrBuf), Error> = Deserializable::deserialize(&mut deserializer); + let value: (int, StrBuf) = Deserializable::deserialize(&mut deserializer).unwrap(); - assert_eq!(value.unwrap(), (5, "a".to_strbuf())); + assert_eq!(value, (5, "a".to_strbuf())); } #[test] @@ -709,9 +815,75 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result<((), (), (int, StrBuf)), Error> = Deserializable::deserialize(&mut deserializer); + let value: ((), (), (int, StrBuf)) = Deserializable::deserialize(&mut deserializer).unwrap(); - assert_eq!(value.unwrap(), ((), (), (5, "a".to_strbuf()))); + assert_eq!(value, ((), (), (5, "a".to_strbuf()))); + } + + #[test] + fn test_tokens_struct_empty() { + let tokens = vec!( + StructStart("Outer"), + StructField("inner"), + SeqStart(0), + End, + End, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Outer = Deserializable::deserialize(&mut deserializer).unwrap(); + + assert_eq!(value, Outer { inner: vec!() }); + } + + #[test] + fn test_tokens_struct() { + let tokens = vec!( + StructStart("Outer"), + StructField("inner"), + SeqStart(1), + Sep, + StructStart("Inner"), + StructField("a"), + Null, + + StructField("b"), + Uint(5), + + StructField("c"), + MapStart(1), + Sep, + TupleStart(2), + Sep, + StrBuf("abc".to_strbuf()), + + Sep, + Option(true), + Char('c'), + End, + End, + End, + End, + End, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Outer = Deserializable::deserialize(&mut deserializer).unwrap(); + + let mut map = HashMap::new(); + map.insert("abc".to_strbuf(), Some('c')); + + assert_eq!( + value, + Outer { + inner: vec!( + Inner { + a: (), + b: 5, + c: map, + }, + ) + }); } #[test] @@ -722,9 +894,9 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result, Error> = Deserializable::deserialize(&mut deserializer); + let value: Vec = Deserializable::deserialize(&mut deserializer).unwrap(); - assert_eq!(value.unwrap(), vec!()); + assert_eq!(value, vec!()); } #[test] @@ -743,9 +915,9 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result, Error> = Deserializable::deserialize(&mut deserializer); + let value: Vec = Deserializable::deserialize(&mut deserializer).unwrap(); - assert_eq!(value.unwrap(), vec!(5, 6, 7)); + assert_eq!(value, vec!(5, 6, 7)); } #[test] @@ -782,9 +954,9 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result>, Error> = Deserializable::deserialize(&mut deserializer); + let value: Vec> = Deserializable::deserialize(&mut deserializer).unwrap(); - assert_eq!(value.unwrap(), vec!(vec!(1), vec!(2, 3), vec!(4, 5, 6))); + assert_eq!(value, vec!(vec!(1), vec!(2, 3), vec!(4, 5, 6))); } #[test] @@ -812,13 +984,13 @@ mod tests { ); let mut deserializer = TokenDeserializer::new(tokens); - let value: Result, Error> = Deserializable::deserialize(&mut deserializer); + let value: HashMap = Deserializable::deserialize(&mut deserializer).unwrap(); let mut map = HashMap::new(); map.insert(5, "a".to_strbuf()); map.insert(6, "b".to_strbuf()); - assert_eq!(value.unwrap(), map); + assert_eq!(value, map); } #[bench] @@ -838,9 +1010,9 @@ mod tests { ); let mut d = TokenDeserializer::new(tokens); - let value: Result, Error> = Deserializable::deserialize(&mut d); + let value: Vec = Deserializable::deserialize(&mut d).unwrap(); - assert_eq!(value.unwrap(), vec!(5, 6, 7)); + assert_eq!(value, vec!(5, 6, 7)); }) } @@ -850,9 +1022,9 @@ mod tests { let ints = vec!(5, 6, 7); let mut d = IntsDeserializer::new(ints); - let value: Result, Error> = Deserializable::deserialize(&mut d); + let value: Vec = Deserializable::deserialize(&mut d).unwrap(); - assert_eq!(value.unwrap(), vec!(5, 6, 7)); + assert_eq!(value, vec!(5, 6, 7)); }) } @@ -862,9 +1034,9 @@ mod tests { let ints = vec!(5, 6, 7); let mut d = IntsDecoder::new(ints); - let value: Result, Error> = Decodable::decode(&mut d); + let value: Vec = Decodable::decode(&mut d).unwrap(); - assert_eq!(value.unwrap(), vec!(5, 6, 7)); + assert_eq!(value, vec!(5, 6, 7)); }) } }