diff --git a/de.rs b/de.rs index 411333b4..2c24b411 100644 --- a/de.rs +++ b/de.rs @@ -438,7 +438,7 @@ mod tests { ////////////////////////////////////////////////////////////////////////////// - #[deriving(Eq, Show)] + #[deriving(Clone, Eq, Show, Decodable)] struct Inner { a: (), b: uint, @@ -459,7 +459,7 @@ mod tests { ////////////////////////////////////////////////////////////////////////////// - #[deriving(Eq, Show)] + #[deriving(Clone, Eq, Show, Decodable)] struct Outer { inner: Vec, } @@ -954,6 +954,216 @@ mod tests { ////////////////////////////////////////////////////////////////////////////// + #[deriving(Show)] + enum OuterDecoderState { + OuterDecoderOuterState(Outer), + OuterDecoderInnerState(Inner), + OuterDecoderNullState, + OuterDecoderUintState(uint), + OuterDecoderCharState(char), + OuterDecoderStrState(StrBuf), + OuterDecoderFieldState(&'static str), + OuterDecoderVecState(Vec), + OuterDecoderMapState(HashMap>), + OuterDecoderOptionState(bool), + } + + struct OuterDecoder { + stack: Vec, + + } + + impl OuterDecoder { + #[inline] + fn new(animal: Outer) -> OuterDecoder { + OuterDecoder { + stack: vec!(OuterDecoderOuterState(animal)), + } + } + } + + impl Decoder for OuterDecoder { + // Primitive types: + #[inline] + fn read_nil(&mut self) -> Result<(), Error> { + match self.stack.pop() { + Some(OuterDecoderNullState) => Ok(()), + _ => Err(SyntaxError), + } + } + #[inline] + fn read_uint(&mut self) -> Result { + match self.stack.pop() { + Some(OuterDecoderUintState(value)) => Ok(value), + _ => Err(SyntaxError), + } + } + fn read_u64(&mut self) -> Result { Err(SyntaxError) } + fn read_u32(&mut self) -> Result { Err(SyntaxError) } + fn read_u16(&mut self) -> Result { Err(SyntaxError) } + fn read_u8(&mut self) -> Result { Err(SyntaxError) } + fn read_int(&mut self) -> Result { Err(SyntaxError) } + fn read_i64(&mut self) -> Result { Err(SyntaxError) } + fn read_i32(&mut self) -> Result { Err(SyntaxError) } + fn read_i16(&mut self) -> Result { Err(SyntaxError) } + fn read_i8(&mut self) -> Result { Err(SyntaxError) } + fn read_bool(&mut self) -> Result { Err(SyntaxError) } + fn read_f64(&mut self) -> Result { Err(SyntaxError) } + fn read_f32(&mut self) -> Result { Err(SyntaxError) } + #[inline] + fn read_char(&mut self) -> Result { + match self.stack.pop() { + Some(OuterDecoderCharState(c)) => Ok(c), + _ => Err(SyntaxError), + } + } + #[inline] + fn read_str(&mut self) -> Result { + match self.stack.pop() { + Some(OuterDecoderStrState(value)) => Ok(value), + _ => Err(SyntaxError), + } + } + + // Compound types: + fn read_enum(&mut self, _name: &str, _f: |&mut OuterDecoder| -> Result) -> Result { Err(SyntaxError) } + + fn read_enum_variant(&mut self, + _names: &[&str], + _f: |&mut OuterDecoder, uint| -> Result) + -> Result { Err(SyntaxError) } + fn read_enum_variant_arg(&mut self, + _a_idx: uint, + _f: |&mut OuterDecoder| -> Result) + -> Result { Err(SyntaxError) } + + fn read_enum_struct_variant(&mut self, + _names: &[&str], + _f: |&mut OuterDecoder, uint| -> Result) + -> Result { Err(SyntaxError) } + fn read_enum_struct_variant_field(&mut self, + _f_name: &str, + _f_idx: uint, + _f: |&mut OuterDecoder| -> Result) + -> Result { Err(SyntaxError) } + + #[inline] + fn read_struct(&mut self, s_name: &str, _len: uint, f: |&mut OuterDecoder| -> Result) -> Result { + match self.stack.pop() { + Some(OuterDecoderOuterState(Outer { inner: inner })) => { + if s_name == "Outer" { + self.stack.push(OuterDecoderVecState(inner)); + self.stack.push(OuterDecoderFieldState("inner")); + f(self) + } else { + Err(SyntaxError) + } + } + Some(OuterDecoderInnerState(Inner { a: (), b: b, c: c })) => { + if s_name == "Inner" { + self.stack.push(OuterDecoderMapState(c)); + self.stack.push(OuterDecoderFieldState("c")); + + self.stack.push(OuterDecoderUintState(b)); + self.stack.push(OuterDecoderFieldState("b")); + + self.stack.push(OuterDecoderNullState); + self.stack.push(OuterDecoderFieldState("a")); + f(self) + } else { + Err(SyntaxError) + } + } + _ => Err(SyntaxError), + } + } + #[inline] + fn read_struct_field(&mut self, f_name: &str, _f_idx: uint, f: |&mut OuterDecoder| -> Result) -> Result { + match self.stack.pop() { + Some(OuterDecoderFieldState(name)) => { + if f_name == name { + f(self) + } else { + Err(SyntaxError) + } + } + _ => Err(SyntaxError) + } + } + + fn read_tuple(&mut self, _f: |&mut OuterDecoder, uint| -> Result) -> Result { Err(SyntaxError) } + fn read_tuple_arg(&mut self, _a_idx: uint, _f: |&mut OuterDecoder| -> Result) -> Result { Err(SyntaxError) } + + fn read_tuple_struct(&mut self, + _s_name: &str, + _f: |&mut OuterDecoder, uint| -> Result) + -> Result { Err(SyntaxError) } + fn read_tuple_struct_arg(&mut self, + _a_idx: uint, + _f: |&mut OuterDecoder| -> Result) + -> Result { Err(SyntaxError) } + + // Specialized types: + #[inline] + fn read_option(&mut self, f: |&mut OuterDecoder, bool| -> Result) -> Result { + match self.stack.pop() { + Some(OuterDecoderOptionState(b)) => f(self, b), + _ => Err(SyntaxError), + } + } + + #[inline] + fn read_seq(&mut self, f: |&mut OuterDecoder, uint| -> Result) -> Result { + match self.stack.pop() { + Some(OuterDecoderVecState(value)) => { + let len = value.len(); + for inner in value.move_iter().rev() { + self.stack.push(OuterDecoderInnerState(inner)); + } + f(self, len) + } + _ => Err(SyntaxError) + } + } + #[inline] + fn read_seq_elt(&mut self, _idx: uint, f: |&mut OuterDecoder| -> Result) -> Result { + f(self) + } + + #[inline] + fn read_map(&mut self, f: |&mut OuterDecoder, uint| -> Result) -> Result { + match self.stack.pop() { + Some(OuterDecoderMapState(map)) => { + let len = map.len(); + for (key, value) in map.move_iter() { + match value { + Some(c) => { + self.stack.push(OuterDecoderCharState(c)); + self.stack.push(OuterDecoderOptionState(true)); + } + None => { + self.stack.push(OuterDecoderOptionState(false)); + } + } + self.stack.push(OuterDecoderStrState(key)); + } + f(self, len) + } + _ => Err(SyntaxError), + } + } + #[inline] + fn read_map_elt_key(&mut self, _idx: uint, f: |&mut OuterDecoder| -> Result) -> Result { + f(self) + } + #[inline] + fn read_map_elt_val(&mut self, _idx: uint, f: |&mut OuterDecoder| -> Result) -> Result { + f(self) + } + } + + ////////////////////////////////////////////////////////////////////////////// + #[test] fn test_tokens_int() { let tokens = vec!( @@ -1338,10 +1548,10 @@ mod tests { b.iter(|| { let animal = Frog("Henry".to_strbuf(), 349); - let mut d = AnimalDecoder::new(animal); + let mut d = AnimalDecoder::new(animal.clone()); let value: Animal = Decodable::decode(&mut d).unwrap(); - assert_eq!(value, Frog("Henry".to_strbuf(), 349)); + assert_eq!(value, animal); }) } @@ -1350,10 +1560,33 @@ mod tests { b.iter(|| { let animal = Frog("Henry".to_strbuf(), 349); - let mut d = AnimalDeserializer::new(animal); + let mut d = AnimalDeserializer::new(animal.clone()); let value: Animal = Deserializable::deserialize(&mut d).unwrap(); - assert_eq!(value, Frog("Henry".to_strbuf(), 349)); + assert_eq!(value, animal); + }) + } + + #[bench] + fn bench_struct_decoder(b: &mut Bencher) { + b.iter(|| { + let mut map = HashMap::new(); + map.insert("abc".to_strbuf(), Some('c')); + + let outer = Outer { + inner: vec!( + Inner { + a: (), + b: 5, + c: map, + }, + ) + }; + + let mut d = OuterDecoder::new(outer.clone()); + let value: Outer = Decodable::decode(&mut d).unwrap(); + + assert_eq!(value, outer); }) } }