From 9bd57645748cff5ad12fb03b46ea234728066ce6 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Fri, 16 May 2014 07:15:02 -0700 Subject: [PATCH] initial commit --- de.rs | 758 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 758 insertions(+) create mode 100644 de.rs diff --git a/de.rs b/de.rs new file mode 100644 index 00000000..791601c9 --- /dev/null +++ b/de.rs @@ -0,0 +1,758 @@ +extern crate collections; + +use std::hash::Hash; +use collections::HashMap; + +#[deriving(Clone, Eq)] +pub enum Token { + Int(int), + StrBuf(StrBuf), + CollectionStart, + CollectionSep, + CollectionEnd, +} + +pub trait Deserializer: Iterator> { + fn end_of_stream_error(&self) -> E; + + fn syntax_error(&self) -> E; + + #[inline] + fn expect_int(&mut self) -> Result { + match self.next() { + Some(Ok(Int(value))) => Ok(value), + Some(Ok(_)) => Err(self.syntax_error()), + Some(Err(err)) => Err(err), + None => Err(self.end_of_stream_error()), + } + } + + #[inline] + fn expect_str(&mut self) -> Result { + match self.next() { + Some(Ok(StrBuf(value))) => Ok(value), + Some(Ok(_)) => Err(self.syntax_error()), + Some(Err(err)) => Err(err), + None => Err(self.end_of_stream_error()), + } + } + + #[inline] + fn expect_collection< + T: Deserializable, + C: FromIterator + >(&mut self) -> Result { + try!(self.expect_collection_start()); + + let mut err = None; + + let values: C = FromIterator::from_iter( + Batch::new(self, |d| { + let token = match d.next() { + Some(token) => token, + None => { return None; } + }; + + match token { + Ok(CollectionSep) => { + let value: Result = Deserializable::deserialize(d); + match value { + Ok(value) => Some(value), + Err(e) => { + err = Some(e); + None + } + } + } + Ok(CollectionEnd) => { + None + } + Ok(_) => { + err = Some(d.syntax_error()); + None + } + Err(e) => { + err = Some(e); + None + } + } + + }) + ); + + match err { + None => Ok(values), + Some(err) => Err(err), + } + } + + #[inline] + fn expect_collection_start(&mut self) -> Result<(), E> { + match self.next() { + Some(Ok(CollectionStart)) => Ok(()), + Some(Ok(_)) => Err(self.syntax_error()), + Some(Err(err)) => Err(err), + None => Err(self.end_of_stream_error()), + } + } + + #[inline] + fn expect_collection_sep(&mut self) -> Result<(), E> { + match self.next() { + Some(Ok(CollectionSep)) => Ok(()), + Some(Ok(_)) => Err(self.syntax_error()), + Some(Err(err)) => Err(err), + None => Err(self.end_of_stream_error()), + } + } + + #[inline] + fn expect_collection_end(&mut self) -> Result<(), E> { + match self.next() { + Some(Ok(CollectionEnd)) => Ok(()), + Some(Ok(_)) => Err(self.syntax_error()), + Some(Err(err)) => Err(err), + None => Err(self.end_of_stream_error()), + } + } + + #[inline] + fn expect_collection_sep_or_end(&mut self) -> Result { + match self.next() { + Some(Ok(CollectionSep)) => Ok(false), + Some(Ok(CollectionEnd)) => Ok(true), + Some(Ok(_)) => Err(self.syntax_error()), + Some(Err(err)) => Err(err), + None => Err(self.end_of_stream_error()), + } + } +} + +pub trait Deserializable> { + fn deserialize(d: &mut D) -> Result; +} + +////////////////////////////////////////////////////////////////////////////// + +impl< + E, + D: Deserializer +> Deserializable for int { + #[inline] + fn deserialize(d: &mut D) -> Result { + d.expect_int() + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl< + E, + D: Deserializer +> Deserializable for StrBuf { + #[inline] + fn deserialize(d: &mut D) -> Result { + d.expect_str() + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl< + E, + D: Deserializer, + T: Deserializable +> Deserializable for Option { + #[inline] + fn deserialize(_d: &mut D) -> Result, E> { + fail!() + //d.expect_collection() + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl< + E, + D: Deserializer, + T: Deserializable +> Deserializable for Vec { + #[inline] + fn deserialize(d: &mut D) -> Result, E> { + d.expect_collection() + } +} + +impl< + E, + D: Deserializer, + K: Deserializable + TotalEq + Hash, + V: Deserializable +> Deserializable for HashMap { + #[inline] + fn deserialize(d: &mut D) -> Result, E> { + d.expect_collection() + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl< + E, + D: Deserializer +> Deserializable for () { + #[inline] + fn deserialize(d: &mut D) -> Result<(), E> { + try!(d.expect_collection_start()); + try!(d.expect_collection_end()); + + Ok(()) + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl< + E, + D: Deserializer, + T0: Deserializable +> Deserializable for (T0,) { + #[inline] + fn deserialize(d: &mut D) -> Result<(T0,), E> { + try!(d.expect_collection_start()); + + try!(d.expect_collection_sep()); + let x0 = try!(Deserializable::deserialize(d)); + + try!(d.expect_collection_end()); + + Ok((x0,)) + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl< + E, + D: Deserializer, + T0: Deserializable, + T1: Deserializable +> Deserializable for (T0, T1) { + #[inline] + fn deserialize(d: &mut D) -> Result<(T0, T1), E> { + try!(d.expect_collection_start()); + + try!(d.expect_collection_sep()); + let x0 = try!(Deserializable::deserialize(d)); + + try!(d.expect_collection_sep()); + let x1 = try!(Deserializable::deserialize(d)); + + try!(d.expect_collection_end()); + + Ok((x0, x1)) + } +} + +////////////////////////////////////////////////////////////////////////////// + +struct Batch<'a, A, B, T> { + iter: &'a mut T, + f: |&mut T|: 'a -> Option, +} + +impl<'a, A, B, T: Iterator> Batch<'a, A, B, T> { + #[inline] + fn new(iter: &'a mut T, f: |&mut T|: 'a -> Option) -> Batch<'a, A, B, T> { + Batch { + iter: iter, + f: f, + } + } +} + +impl<'a, A, B, T: Iterator> Iterator for Batch<'a, A, B, T> { + #[inline] + fn next(&mut self) -> Option { + (self.f)(self.iter) + } +} + +////////////////////////////////////////////////////////////////////////////// + +#[cfg(test)] +mod tests { + extern crate collections; + extern crate serialize; + extern crate test; + + use std::vec; + use self::collections::HashMap; + use self::test::Bencher; + use self::serialize::{Decoder, Decodable}; + + use super::{Token, Int, StrBuf, CollectionStart, CollectionSep, CollectionEnd}; + use super::{Deserializer, Deserializable}; + + ////////////////////////////////////////////////////////////////////////////// + + #[deriving(Show)] + enum Error { + EndOfStream, + SyntaxError, + } + + ////////////////////////////////////////////////////////////////////////////// + + struct TokenDeserializer { + tokens: Vec, + } + + impl TokenDeserializer { + #[inline] + fn new(tokens: Vec) -> TokenDeserializer { + TokenDeserializer { + tokens: tokens, + } + } + } + + impl Iterator> for TokenDeserializer { + #[inline] + fn next(&mut self) -> Option> { + match self.tokens.shift() { + None => None, + Some(token) => Some(Ok(token)), + } + } + } + + impl Deserializer for TokenDeserializer { + #[inline] + fn end_of_stream_error(&self) -> Error { + EndOfStream + } + + #[inline] + fn syntax_error(&self) -> Error { + SyntaxError + } + } + + ////////////////////////////////////////////////////////////////////////////// + + #[deriving(Eq, Show)] + enum IntsDeserializerState { + Start, + Sep, + Value, + End, + } + + struct IntsDeserializer { + state: IntsDeserializerState, + iter: vec::MoveItems, + value: Option + } + + impl IntsDeserializer { + #[inline] + fn new(values: Vec) -> IntsDeserializer { + IntsDeserializer { + state: Start, + iter: values.move_iter(), + value: None, + } + } + } + + impl Iterator> for IntsDeserializer { + #[inline] + fn next(&mut self) -> Option> { + match self.state { + Start => { + self.state = Sep; + Some(Ok(CollectionStart)) + } + Sep => { + match self.iter.next() { + Some(value) => { + self.state = Value; + self.value = Some(value); + Some(Ok(CollectionSep)) + } + None => { + self.state = End; + Some(Ok(CollectionEnd)) + } + } + } + Value => { + self.state = Sep; + match self.value.take() { + Some(value) => Some(Ok(Int(value))), + None => Some(Err(self.end_of_stream_error())), + } + } + End => { + None + } + } + } + } + + impl Deserializer for IntsDeserializer { + #[inline] + fn end_of_stream_error(&self) -> Error { + EndOfStream + } + + #[inline] + fn syntax_error(&self) -> Error { + SyntaxError + } + + #[inline] + fn expect_int(&mut self) -> Result { + assert_eq!(self.state, Value); + + self.state = Sep; + + match self.value.take() { + Some(value) => Ok(value), + None => Err(self.end_of_stream_error()), + } + } + } + + struct IntsDecoder { + iter: vec::MoveItems, + } + + impl IntsDecoder { + #[inline] + fn new(values: Vec) -> IntsDecoder { + IntsDecoder { + iter: values.move_iter() + } + } + } + + impl Decoder for IntsDecoder { + // 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.iter.next() { + Some(value) => Ok(value), + None => Err(EndOfStream), + } + } + 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) } + fn read_str(&mut self) -> Result<~str, Error> { Err(SyntaxError) } + + // Compound types: + fn read_enum(&mut self, _name: &str, _f: |&mut IntsDecoder| -> Result) -> Result { Err(SyntaxError) } + + fn read_enum_variant(&mut self, + _names: &[&str], + _f: |&mut IntsDecoder, uint| -> Result) + -> Result { Err(SyntaxError) } + fn read_enum_variant_arg(&mut self, + _a_idx: uint, + _f: |&mut IntsDecoder| -> Result) + -> Result { Err(SyntaxError) } + + fn read_enum_struct_variant(&mut self, + _names: &[&str], + _f: |&mut IntsDecoder, uint| -> Result) + -> Result { Err(SyntaxError) } + fn read_enum_struct_variant_field(&mut self, + _f_name: &str, + _f_idx: uint, + _f: |&mut IntsDecoder| -> Result) + -> Result { Err(SyntaxError) } + + fn read_struct(&mut self, _s_name: &str, _len: uint, _f: |&mut IntsDecoder| -> Result) + -> Result { Err(SyntaxError) } + fn read_struct_field(&mut self, + _f_name: &str, + _f_idx: uint, + _f: |&mut IntsDecoder| -> Result) + -> Result { Err(SyntaxError) } + + fn read_tuple(&mut self, _f: |&mut IntsDecoder, uint| -> Result) -> Result { Err(SyntaxError) } + fn read_tuple_arg(&mut self, _a_idx: uint, _f: |&mut IntsDecoder| -> Result) -> Result { Err(SyntaxError) } + + fn read_tuple_struct(&mut self, + _s_name: &str, + _f: |&mut IntsDecoder, uint| -> Result) + -> Result { Err(SyntaxError) } + fn read_tuple_struct_arg(&mut self, + _a_idx: uint, + _f: |&mut IntsDecoder| -> Result) + -> Result { Err(SyntaxError) } + + // Specialized types: + fn read_option(&mut self, _f: |&mut IntsDecoder, bool| -> Result) -> Result { Err(SyntaxError) } + + #[inline] + fn read_seq(&mut self, f: |&mut IntsDecoder, uint| -> Result) -> Result { + f(self, 3) + } + #[inline] + fn read_seq_elt(&mut self, _idx: uint, f: |&mut IntsDecoder| -> Result) -> Result { + f(self) + } + + fn read_map(&mut self, _f: |&mut IntsDecoder, uint| -> Result) -> Result { Err(SyntaxError) } + fn read_map_elt_key(&mut self, _idx: uint, _f: |&mut IntsDecoder| -> Result) -> Result { Err(SyntaxError) } + fn read_map_elt_val(&mut self, _idx: uint, _f: |&mut IntsDecoder| -> Result) -> Result { Err(SyntaxError) } + } + + #[test] + fn test_tokens_int() { + let tokens = vec!( + Int(5), + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Result = Deserializable::deserialize(&mut deserializer); + + assert_eq!(value.unwrap(), 5); + } + + #[test] + fn test_tokens_strbuf() { + let tokens = vec!( + StrBuf("a".to_strbuf()), + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Result = Deserializable::deserialize(&mut deserializer); + + assert_eq!(value.unwrap(), "a".to_strbuf()); + } + + + #[test] + fn test_tokens_tuple_empty() { + let tokens = vec!( + CollectionStart, + CollectionEnd, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Result<(), Error> = Deserializable::deserialize(&mut deserializer); + + assert_eq!(value.unwrap(), ()); + } + + #[test] + fn test_tokens_tuple() { + let tokens = vec!( + CollectionStart, + CollectionSep, + Int(5), + + CollectionSep, + StrBuf("a".to_strbuf()), + CollectionEnd, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Result<(int, StrBuf), Error> = Deserializable::deserialize(&mut deserializer); + + assert_eq!(value.unwrap(), (5, "a".to_strbuf())); + } + + #[test] + fn test_tokens_tuple_compound() { + let tokens = vec!( + CollectionStart, + CollectionSep, + CollectionStart, + CollectionEnd, + + CollectionSep, + CollectionStart, + CollectionSep, + Int(5), + CollectionSep, + StrBuf("a".to_strbuf()), + CollectionEnd, + CollectionEnd, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Result<((), (int, StrBuf)), Error> = Deserializable::deserialize(&mut deserializer); + + assert_eq!(value.unwrap(), ((), (5, "a".to_strbuf()))); + } + + #[test] + fn test_tokens_vec_empty() { + let tokens = vec!( + CollectionStart, + CollectionEnd, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Result, Error> = Deserializable::deserialize(&mut deserializer); + + assert_eq!(value.unwrap(), vec!()); + } + + #[test] + fn test_tokens_vec() { + let tokens = vec!( + CollectionStart, + CollectionSep, + Int(5), + + CollectionSep, + Int(6), + + CollectionSep, + Int(7), + CollectionEnd, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Result, Error> = Deserializable::deserialize(&mut deserializer); + + assert_eq!(value.unwrap(), vec!(5, 6, 7)); + } + + #[test] + fn test_tokens_vec_compound() { + let tokens = vec!( + CollectionStart, + CollectionSep, + CollectionStart, + CollectionSep, + Int(1), + CollectionEnd, + + CollectionSep, + CollectionStart, + CollectionSep, + Int(2), + + CollectionSep, + Int(3), + CollectionEnd, + + CollectionSep, + CollectionStart, + CollectionSep, + Int(4), + + CollectionSep, + Int(5), + + CollectionSep, + Int(6), + CollectionEnd, + CollectionEnd, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Result>, Error> = Deserializable::deserialize(&mut deserializer); + + assert_eq!(value.unwrap(), vec!(vec!(1), vec!(2, 3), vec!(4, 5, 6))); + } + + #[test] + fn test_tokens_hashmap() { + let tokens = vec!( + CollectionStart, + CollectionSep, + CollectionStart, + CollectionSep, + Int(5), + + CollectionSep, + StrBuf("a".to_strbuf()), + CollectionEnd, + + CollectionSep, + CollectionStart, + CollectionSep, + Int(6), + + CollectionSep, + StrBuf("b".to_strbuf()), + CollectionEnd, + CollectionEnd, + ); + + let mut deserializer = TokenDeserializer::new(tokens); + let value: Result, Error> = Deserializable::deserialize(&mut deserializer); + + let mut map = HashMap::new(); + map.insert(5, "a".to_strbuf()); + map.insert(6, "b".to_strbuf()); + + assert_eq!(value.unwrap(), map); + } + + #[bench] + fn bench_dummy_deserializer(b: &mut Bencher) { + b.iter(|| { + let tokens = vec!( + CollectionStart, + CollectionSep, + Int(5), + + CollectionSep, + Int(6), + + CollectionSep, + Int(7), + CollectionEnd, + ); + + let mut d = TokenDeserializer::new(tokens); + let value: Result, Error> = Deserializable::deserialize(&mut d); + + assert_eq!(value.unwrap(), vec!(5, 6, 7)); + }) + } + + #[bench] + fn bench_ints_deserializer(b: &mut Bencher) { + b.iter(|| { + let ints = vec!(5, 6, 7); + + let mut d = IntsDeserializer::new(ints); + let value: Result, Error> = Deserializable::deserialize(&mut d); + + assert_eq!(value.unwrap(), vec!(5, 6, 7)); + }) + } + + #[bench] + fn bench_ints_decoder(b: &mut Bencher) { + b.iter(|| { + let ints = vec!(5, 6, 7); + + let mut d = IntsDecoder::new(ints); + let value: Result, Error> = Decodable::decode(&mut d); + + assert_eq!(value.unwrap(), vec!(5, 6, 7)); + }) + } +}