use test::Bencher; use serialize::{Decoder, Decodable}; use de::{Deserializer, Deserializable, Token}; ////////////////////////////////////////////////////////////////////////////// #[deriving(Clone, Eq, Show, Decodable)] enum Animal { Dog, Frog(StrBuf, int) } impl> Deserializable for Animal { #[inline] fn deserialize_token(d: &mut D, token: Token) -> Result { match try!(d.expect_enum_start(token, "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, SyntaxError, } ////////////////////////////////////////////////////////////////////////////// mod decoder { use serialize::Decoder; use super::{Animal, Dog, Frog, Error, SyntaxError}; enum State { AnimalState(Animal), DogState, FrogState, IntState(int), StrState(StrBuf), } pub struct AnimalDecoder { stack: Vec, } impl AnimalDecoder { #[inline] pub fn new(animal: Animal) -> AnimalDecoder { AnimalDecoder { stack: vec!(AnimalState(animal)), } } } impl Decoder for AnimalDecoder { // Primitive types: fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) } fn read_uint(&mut self) -> Result { 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) } #[inline] fn read_int(&mut self) -> Result { match self.stack.pop() { Some(IntState(x)) => Ok(x), _ => 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) } fn read_char(&mut self) -> Result { Err(SyntaxError) } #[inline] fn read_str(&mut self) -> Result { match self.stack.pop() { Some(StrState(x)) => Ok(x), _ => Err(SyntaxError), } } // Compound types: #[inline] fn read_enum(&mut self, name: &str, f: |&mut AnimalDecoder| -> Result) -> Result { match self.stack.pop() { Some(AnimalState(animal)) => { self.stack.push(AnimalState(animal)); if name == "Animal" { f(self) } else { Err(SyntaxError) } } _ => Err(SyntaxError) } } #[inline] fn read_enum_variant(&mut self, names: &[&str], f: |&mut AnimalDecoder, uint| -> Result) -> Result { let name = match self.stack.pop() { Some(AnimalState(Dog)) => "Dog", Some(AnimalState(Frog(x0, x1))) => { self.stack.push(IntState(x1)); self.stack.push(StrState(x0)); "Frog" } _ => { return Err(SyntaxError); } }; let idx = match names.iter().position(|n| *n == name) { Some(idx) => idx, None => { return Err(SyntaxError); } }; f(self, idx) } #[inline] fn read_enum_variant_arg(&mut self, _a_idx: uint, f: |&mut AnimalDecoder| -> Result) -> Result { f(self) } fn read_enum_struct_variant(&mut self, _names: &[&str], _f: |&mut AnimalDecoder, uint| -> Result) -> Result { Err(SyntaxError) } fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: uint, _f: |&mut AnimalDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_struct(&mut self, _s_name: &str, _len: uint, _f: |&mut AnimalDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_struct_field(&mut self, _f_name: &str, _f_idx: uint, _f: |&mut AnimalDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_tuple(&mut self, _f: |&mut AnimalDecoder, uint| -> Result) -> Result { Err(SyntaxError) } fn read_tuple_arg(&mut self, _a_idx: uint, _f: |&mut AnimalDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_tuple_struct(&mut self, _s_name: &str, _f: |&mut AnimalDecoder, uint| -> Result) -> Result { Err(SyntaxError) } fn read_tuple_struct_arg(&mut self, _a_idx: uint, _f: |&mut AnimalDecoder| -> Result) -> Result { Err(SyntaxError) } // Specialized types: fn read_option(&mut self, _f: |&mut AnimalDecoder, bool| -> Result) -> Result { Err(SyntaxError) } #[inline] fn read_seq(&mut self, f: |&mut AnimalDecoder, uint| -> Result) -> Result { f(self, 3) } #[inline] fn read_seq_elt(&mut self, _idx: uint, f: |&mut AnimalDecoder| -> Result) -> Result { f(self) } fn read_map(&mut self, _f: |&mut AnimalDecoder, uint| -> Result) -> Result { Err(SyntaxError) } fn read_map_elt_key(&mut self, _idx: uint, _f: |&mut AnimalDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_map_elt_val(&mut self, _idx: uint, _f: |&mut AnimalDecoder| -> Result) -> Result { Err(SyntaxError) } } } ////////////////////////////////////////////////////////////////////////////// mod deserializer { use super::{Animal, Dog, Frog, Error, EndOfStream, SyntaxError}; use de::Deserializer; use de::{Token, Int, StrBuf, EnumStart, End}; enum State { AnimalState(Animal), IntState(int), StrState(StrBuf), EndState, } pub struct AnimalDeserializer { stack: Vec, } impl AnimalDeserializer { #[inline] pub fn new(animal: Animal) -> AnimalDeserializer { AnimalDeserializer { stack: vec!(AnimalState(animal)), } } } impl Iterator> for AnimalDeserializer { #[inline] fn next(&mut self) -> Option> { match self.stack.pop() { Some(AnimalState(Dog)) => { self.stack.push(EndState); Some(Ok(EnumStart("Animal", "Dog"))) } Some(AnimalState(Frog(x0, x1))) => { self.stack.push(EndState); self.stack.push(IntState(x1)); self.stack.push(StrState(x0)); Some(Ok(EnumStart("Animal", "Frog"))) } Some(IntState(x)) => { Some(Ok(Int(x))) } Some(StrState(x)) => { Some(Ok(StrBuf(x))) } Some(EndState) => { Some(Ok(End)) } None => None, } } } impl Deserializer for AnimalDeserializer { #[inline] fn end_of_stream_error(&self) -> Error { EndOfStream } #[inline] fn syntax_error(&self) -> Error { SyntaxError } } } ////////////////////////////////////////////////////////////////////////////// #[bench] fn bench_enum_decoder(b: &mut Bencher) { b.iter(|| { let animal = Frog("Henry".to_strbuf(), 349); let mut d = decoder::AnimalDecoder::new(animal.clone()); let value: Animal = Decodable::decode(&mut d).unwrap(); assert_eq!(value, animal); }) } #[bench] fn bench_enum_deserializer(b: &mut Bencher) { b.iter(|| { let animal = Frog("Henry".to_strbuf(), 349); let mut d = deserializer::AnimalDeserializer::new(animal.clone()); let value: Animal = Deserializable::deserialize(&mut d).unwrap(); assert_eq!(value, animal); }) }