use test::Bencher; use std::error; use std::fmt; use rustc_serialize::{Decoder, Decodable}; use serde; use serde::de::{Deserializer, Deserialize}; ////////////////////////////////////////////////////////////////////////////// #[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)] pub enum Animal { Dog, Frog(String, isize) } ////////////////////////////////////////////////////////////////////////////// #[derive(Debug)] pub enum Error { EndOfStream, Syntax, } impl serde::de::Error for Error { fn custom(_: String) -> Error { Error::Syntax } fn end_of_stream() -> Error { Error::EndOfStream } fn unknown_field(_: &str) -> Error { Error::Syntax } fn missing_field(_: &'static str) -> Error { Error::Syntax } } impl fmt::Display for Error { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { formatter.write_str(format!("{:?}", self).as_ref()) } } impl error::Error for Error { fn description(&self) -> &str { "Serde Deserialization Error" } fn cause(&self) -> Option<&error::Error> { None } } ////////////////////////////////////////////////////////////////////////////// mod decoder { use rustc_serialize::Decoder; use super::{Animal, Error}; use super::Animal::{Dog, Frog}; enum State { Animal(Animal), Isize(isize), String(String), } pub struct AnimalDecoder { stack: Vec, } impl AnimalDecoder { #[inline] pub fn new(animal: Animal) -> AnimalDecoder { AnimalDecoder { stack: vec!(State::Animal(animal)), } } } impl Decoder for AnimalDecoder { type Error = Error; fn error(&mut self, _: &str) -> Error { Error::Syntax } // Primitive types: fn read_nil(&mut self) -> Result<(), Error> { Err(Error::Syntax) } fn read_usize(&mut self) -> Result { Err(Error::Syntax) } fn read_u64(&mut self) -> Result { Err(Error::Syntax) } fn read_u32(&mut self) -> Result { Err(Error::Syntax) } fn read_u16(&mut self) -> Result { Err(Error::Syntax) } fn read_u8(&mut self) -> Result { Err(Error::Syntax) } #[inline] fn read_isize(&mut self) -> Result { match self.stack.pop() { Some(State::Isize(x)) => Ok(x), _ => Err(Error::Syntax), } } fn read_i64(&mut self) -> Result { Err(Error::Syntax) } fn read_i32(&mut self) -> Result { Err(Error::Syntax) } fn read_i16(&mut self) -> Result { Err(Error::Syntax) } fn read_i8(&mut self) -> Result { Err(Error::Syntax) } fn read_bool(&mut self) -> Result { Err(Error::Syntax) } fn read_f64(&mut self) -> Result { Err(Error::Syntax) } fn read_f32(&mut self) -> Result { Err(Error::Syntax) } fn read_char(&mut self) -> Result { Err(Error::Syntax) } #[inline] fn read_str(&mut self) -> Result { match self.stack.pop() { Some(State::String(x)) => Ok(x), _ => Err(Error::Syntax), } } // Compound types: #[inline] fn read_enum(&mut self, name: &str, f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { match self.stack.pop() { Some(State::Animal(animal)) => { self.stack.push(State::Animal(animal)); if name == "Animal" { f(self) } else { Err(Error::Syntax) } } _ => Err(Error::Syntax) } } #[inline] fn read_enum_variant(&mut self, names: &[&str], f: F) -> Result where F: FnOnce(&mut AnimalDecoder, usize) -> Result, { let name = match self.stack.pop() { Some(State::Animal(Dog)) => "Dog", Some(State::Animal(Frog(x0, x1))) => { self.stack.push(State::Isize(x1)); self.stack.push(State::String(x0)); "Frog" } _ => { return Err(Error::Syntax); } }; let idx = match names.iter().position(|n| *n == name) { Some(idx) => idx, None => { return Err(Error::Syntax); } }; f(self, idx) } #[inline] fn read_enum_variant_arg(&mut self, _a_idx: usize, f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { f(self) } fn read_enum_struct_variant(&mut self, _names: &[&str], _f: F) -> Result where F: FnOnce(&mut AnimalDecoder, usize) -> Result, { Err(Error::Syntax) } fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { Err(Error::Syntax) } fn read_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { Err(Error::Syntax) } fn read_struct_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { Err(Error::Syntax) } fn read_tuple(&mut self, _len: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { Err(Error::Syntax) } fn read_tuple_arg(&mut self, _a_idx: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { Err(Error::Syntax) } fn read_tuple_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { Err(Error::Syntax) } fn read_tuple_struct_arg(&mut self, _a_idx: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { Err(Error::Syntax) } // Specialized types: fn read_option(&mut self, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder, bool) -> Result, { Err(Error::Syntax) } #[inline] fn read_seq(&mut self, f: F) -> Result where F: FnOnce(&mut AnimalDecoder, usize) -> Result, { f(self, 3) } #[inline] fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { f(self) } fn read_map(&mut self, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder, usize) -> Result, { Err(Error::Syntax) } fn read_map_elt_key(&mut self, _idx: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { Err(Error::Syntax) } fn read_map_elt_val(&mut self, _idx: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { Err(Error::Syntax) } } } ////////////////////////////////////////////////////////////////////////////// mod deserializer { use super::{Animal, Error}; use serde::de; #[derive(Debug)] enum State { Animal(Animal), Isize(isize), Str(&'static str), String(String), UnitState, } pub struct AnimalDeserializer { stack: Vec, } impl AnimalDeserializer { #[inline] pub fn new(animal: Animal) -> AnimalDeserializer { AnimalDeserializer { stack: vec!(State::Animal(animal)), } } } impl de::Deserializer for AnimalDeserializer { type Error = Error; #[inline] fn deserialize(&mut self, mut visitor: V) -> Result where V: de::Visitor, { match self.stack.pop() { Some(State::Isize(value)) => { visitor.visit_isize(value) } Some(State::String(value)) => { visitor.visit_string(value) } Some(State::Str(value)) => { visitor.visit_str(value) } Some(State::UnitState) => { visitor.visit_unit() } Some(_) => { Err(Error::Syntax) } None => { Err(Error::EndOfStream) } } } #[inline] fn deserialize_enum(&mut self, _name: &str, _variants: &[&str], mut visitor: V) -> Result where V: de::EnumVisitor, { match self.stack.pop() { Some(State::Animal(Animal::Dog)) => { self.stack.push(State::UnitState); self.stack.push(State::Str("Dog")); visitor.visit(DogVisitor { de: self, }) } Some(State::Animal(Animal::Frog(x0, x1))) => { self.stack.push(State::Isize(x1)); self.stack.push(State::String(x0)); self.stack.push(State::Str("Frog")); visitor.visit(FrogVisitor { de: self, state: 0, }) } Some(_) => { Err(Error::Syntax) } None => { Err(Error::EndOfStream) } } } } struct DogVisitor<'a> { de: &'a mut AnimalDeserializer, } impl<'a> de::VariantVisitor for DogVisitor<'a> { type Error = Error; fn visit_variant(&mut self) -> Result where V: de::Deserialize { de::Deserialize::deserialize(self.de) } fn visit_unit(&mut self) -> Result<(), Error> { de::Deserialize::deserialize(self.de) } } struct FrogVisitor<'a> { de: &'a mut AnimalDeserializer, state: usize, } impl<'a> de::VariantVisitor for FrogVisitor<'a> { type Error = Error; fn visit_variant(&mut self) -> Result where V: de::Deserialize { de::Deserialize::deserialize(self.de) } fn visit_tuple(&mut self, _len: usize, mut visitor: V) -> Result where V: de::Visitor, { visitor.visit_seq(self) } } impl<'a> de::SeqVisitor for FrogVisitor<'a> { type Error = Error; fn visit(&mut self) -> Result, Error> where T: de::Deserialize, { match self.state { 0 => { self.state += 1; Ok(Some(try!(de::Deserialize::deserialize(self.de)))) } 1 => { self.state += 1; Ok(Some(try!(de::Deserialize::deserialize(self.de)))) } _ => { Ok(None) } } } fn end(&mut self) -> Result<(), Error> { if self.state == 2 { Ok(()) } else { Err(Error::Syntax) } } fn size_hint(&self) -> (usize, Option) { let len = 2 - self.state; (len, Some(len)) } } } ////////////////////////////////////////////////////////////////////////////// #[bench] fn bench_decoder_dog(b: &mut Bencher) { b.iter(|| { let animal = Animal::Dog; let mut d = decoder::AnimalDecoder::new(animal.clone()); let value: Animal = Decodable::decode(&mut d).unwrap(); assert_eq!(value, animal); }) } #[bench] fn bench_decoder_frog(b: &mut Bencher) { b.iter(|| { let animal = Animal::Frog("Henry".to_owned(), 349); let mut d = decoder::AnimalDecoder::new(animal.clone()); let value: Animal = Decodable::decode(&mut d).unwrap(); assert_eq!(value, animal); }) } #[bench] fn bench_deserializer_dog(b: &mut Bencher) { b.iter(|| { let animal = Animal::Dog; let mut d = deserializer::AnimalDeserializer::new(animal.clone()); let value: Animal = Deserialize::deserialize(&mut d).unwrap(); assert_eq!(value, animal); }) } #[bench] fn bench_deserializer_frog(b: &mut Bencher) { b.iter(|| { let animal = Animal::Frog("Henry".to_owned(), 349); let mut d = deserializer::AnimalDeserializer::new(animal.clone()); let value: Animal = Deserialize::deserialize(&mut d).unwrap(); assert_eq!(value, animal); }) }