diff --git a/de.rs b/de.rs index dd53d380..9993322c 100644 --- a/de.rs +++ b/de.rs @@ -24,12 +24,16 @@ pub enum Token { Char(char), Str(&'static str), StrBuf(StrBuf), - Option(bool), TupleStart(uint), + StructStart(&'static str), StructField(&'static str), + + EnumStart(&'static str), + EnumVariant(&'static str), + SeqStart(uint), MapStart(uint), @@ -190,6 +194,26 @@ pub trait Deserializer: Iterator> { } } + #[inline] + fn expect_enum_start<'a>(&mut self, name: &str, variants: &[&str]) -> Result { + match_token! { + EnumStart(n) => { + if name == n { + match_token! { + EnumVariant(n) => { + match variants.iter().position(|variant| *variant == n) { + Some(position) => Ok(position), + None => Err(self.syntax_error()), + } + } + } + } else { + Err(self.syntax_error()) + } + } + } + } + #[inline] fn expect_collection< T: Deserializable, @@ -410,7 +434,8 @@ mod tests { use self::serialize::{Decoder, Decodable}; use super::{Token, Null, Int, Uint, Str, StrBuf, Char, Option}; - use super::{TupleStart, StructStart, StructField, SeqStart, MapStart, Sep, End}; + use super::{TupleStart, StructStart, StructField, EnumStart, EnumVariant}; + use super::{SeqStart, MapStart, Sep, End}; use super::{Deserializer, Deserializable}; ////////////////////////////////////////////////////////////////////////////// @@ -453,6 +478,33 @@ mod tests { ////////////////////////////////////////////////////////////////////////////// + #[deriving(Eq, Show)] + enum Animal { + Dog, + Frog(StrBuf, int) + } + + impl> Deserializable for Animal { + #[inline] + fn deserialize(d: &mut D) -> Result { + match try!(d.expect_enum_start("Animal", ["Dog", "Frog"])) { + 0 => { + try!(d.expect_end()); + Ok(Dog) + } + 1 => { + let x0 = try!(Deserializable::deserialize(d)); + let x1 = try!(Deserializable::deserialize(d)); + try!(d.expect_end()); + Ok(Frog(x0, x1)) + } + _ => unreachable!(), + } + } + } + + ////////////////////////////////////////////////////////////////////////////// + #[deriving(Show)] enum Error { EndOfStream, @@ -886,6 +938,33 @@ mod tests { }); } + #[test] + fn test_tokens_enum() { + let tokens = vec!( + EnumStart("Animal"), + EnumVariant("Dog"), + End, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Animal = Deserializable::deserialize(&mut deserializer).unwrap(); + + assert_eq!(value, Dog); + + let tokens = vec!( + EnumStart("Animal"), + EnumVariant("Frog"), + StrBuf("Henry".to_strbuf()), + Int(349), + End, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Animal = Deserializable::deserialize(&mut deserializer).unwrap(); + + assert_eq!(value, Frog("Henry".to_strbuf(), 349)); + } + #[test] fn test_tokens_vec_empty() { let tokens = vec!(