// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use std::collections::{HashMap, TreeMap}; use std::hash::Hash; ////////////////////////////////////////////////////////////////////////////// pub trait Serializer { fn serialize_null(&mut self) -> Result<(), E>; fn serialize_bool(&mut self, v: bool) -> Result<(), E>; #[inline] fn serialize_int(&mut self, v: int) -> Result<(), E> { self.serialize_i64(v as i64) } #[inline] fn serialize_i8(&mut self, v: i8) -> Result<(), E> { self.serialize_i64(v as i64) } #[inline] fn serialize_i16(&mut self, v: i16) -> Result<(), E> { self.serialize_i64(v as i64) } #[inline] fn serialize_i32(&mut self, v: i32) -> Result<(), E> { self.serialize_i64(v as i64) } #[inline] fn serialize_i64(&mut self, v: i64) -> Result<(), E>; #[inline] fn serialize_uint(&mut self, v: uint) -> Result<(), E> { self.serialize_u64(v as u64) } #[inline] fn serialize_u8(&mut self, v: u8) -> Result<(), E> { self.serialize_u64(v as u64) } #[inline] fn serialize_u16(&mut self, v: u16) -> Result<(), E> { self.serialize_u64(v as u64) } #[inline] fn serialize_u32(&mut self, v: u32) -> Result<(), E> { self.serialize_u64(v as u64) } #[inline] fn serialize_u64(&mut self, v: u64) -> Result<(), E>; #[inline] fn serialize_f32(&mut self, v: f32) -> Result<(), E> { self.serialize_f64(v as f64) } fn serialize_f64(&mut self, v: f64) -> Result<(), E>; fn serialize_char(&mut self, v: char) -> Result<(), E>; fn serialize_str(&mut self, v: &str) -> Result<(), E>; fn serialize_tuple_start(&mut self, len: uint) -> Result<(), E>; fn serialize_tuple_sep(&mut self) -> Result<(), E>; fn serialize_tuple_end(&mut self) -> Result<(), E>; fn serialize_struct_start(&mut self, name: &str, len: uint) -> Result<(), E>; fn serialize_struct_sep(&mut self, name: &str) -> Result<(), E>; fn serialize_struct_end(&mut self) -> Result<(), E>; fn serialize_enum_start(&mut self, name: &str, variant: &str, len: uint) -> Result<(), E>; fn serialize_enum_sep(&mut self) -> Result<(), E>; fn serialize_enum_end(&mut self) -> Result<(), E>; fn serialize_option< T: Serializable >(&mut self, v: &Option) -> Result<(), E>; fn serialize_seq< T: Serializable, Iter: Iterator >(&mut self, iter: Iter) -> Result<(), E>; fn serialize_map< K: Serializable, V: Serializable, Iter: Iterator<(K, V)> >(&mut self, iter: Iter) -> Result<(), E>; } ////////////////////////////////////////////////////////////////////////////// pub trait Serializable, E> { fn serialize(&self, s: &mut S) -> Result<(), E>; } ////////////////////////////////////////////////////////////////////////////// macro_rules! impl_serializable { ($ty:ty, $method:ident, $variant:expr) => { impl<'a, S: Serializer, E> Serializable for $ty { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { s.$method($variant) } } } } impl_serializable!(bool, serialize_bool, *self) impl_serializable!(int, serialize_int, *self) impl_serializable!(i8, serialize_i8, *self) impl_serializable!(i16, serialize_i16, *self) impl_serializable!(i32, serialize_i32, *self) impl_serializable!(i64, serialize_i64, *self) impl_serializable!(uint, serialize_uint, *self) impl_serializable!(u8, serialize_u8, *self) impl_serializable!(u16, serialize_u16, *self) impl_serializable!(u32, serialize_u32, *self) impl_serializable!(u64, serialize_u64, *self) impl_serializable!(f32, serialize_f32, *self) impl_serializable!(f64, serialize_f64, *self) impl_serializable!(char, serialize_char, *self) impl_serializable!(&'a str, serialize_str, *self) impl_serializable!(String, serialize_str, self.as_slice()) impl< 'a, E, S: Serializer, T: Serializable > Serializable for &'a T { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { (*self).serialize(s) } } ////////////////////////////////////////////////////////////////////////////// impl< E, S: Serializer, T: Serializable > Serializable for Option { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { s.serialize_option(self) } } ////////////////////////////////////////////////////////////////////////////// impl< E, S: Serializer, T: Serializable > Serializable for Vec { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { s.serialize_seq(self.iter()) } } ////////////////////////////////////////////////////////////////////////////// impl< E, S: Serializer, K: Serializable + Eq + Hash, V: Serializable > Serializable for HashMap { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { s.serialize_map(self.iter()) } } impl< E, S: Serializer, K: Serializable + Ord, V: Serializable > Serializable for TreeMap { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { s.serialize_map(self.iter()) } } ////////////////////////////////////////////////////////////////////////////// macro_rules! peel { ($name:ident, $($other:ident,)*) => (impl_serialize_tuple!($($other,)*)) } macro_rules! impl_serialize_tuple { () => { impl< E, S: Serializer > Serializable for () { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { s.serialize_null() } } }; ( $($name:ident,)+ ) => { impl< E, S: Serializer, $($name:Serializable),* > Serializable for ($($name,)*) { #[inline] #[allow(uppercase_variables)] fn serialize(&self, s: &mut S) -> Result<(), E> { // FIXME: how can we count macro args? let mut len = 0; $({ let $name = 1; len += $name; })*; let ($(ref $name,)*) = *self; try!(s.serialize_tuple_start(len)); $( try!(s.serialize_tuple_sep()); try!($name.serialize(s)); )* s.serialize_tuple_end() } } peel!($($name,)*) } } impl_serialize_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } ////////////////////////////////////////////////////////////////////////////// #[cfg(test)] mod tests { use std::collections::{HashMap, TreeMap}; use serialize::Decoder; use super::{Serializer, Serializable}; ////////////////////////////////////////////////////////////////////////////// #[deriving(Clone, PartialEq, Show, Decodable)] struct Inner { a: (), b: uint, c: HashMap>, } impl, E> Serializable for Inner { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { try!(s.serialize_struct_start("Inner", 3)); try!(s.serialize_struct_sep("a")); try!(self.a.serialize(s)); try!(s.serialize_struct_sep("b")); try!(self.b.serialize(s)); try!(s.serialize_struct_sep("c")); try!(self.c.serialize(s)); s.serialize_struct_end() } } ////////////////////////////////////////////////////////////////////////////// #[deriving(Clone, PartialEq, Show, Decodable)] struct Outer { inner: Vec, } impl, E> Serializable for Outer { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { try!(s.serialize_struct_start("Outer", 1)); try!(s.serialize_struct_sep("inner")); try!(self.inner.serialize(s)); s.serialize_struct_end() } } ////////////////////////////////////////////////////////////////////////////// #[deriving(Clone, PartialEq, Show, Decodable)] enum Animal { Dog, Frog(String, int) } impl, E> Serializable for Animal { #[inline] fn serialize(&self, s: &mut S) -> Result<(), E> { match *self { Dog => { try!(s.serialize_enum_start("Animal", "Dog", 0)); } Frog(ref x, y) => { try!(s.serialize_enum_start("Animal", "Frog", 2)); try!(s.serialize_enum_sep()); try!(x.serialize(s)); try!(s.serialize_enum_sep()); try!(y.serialize(s)); } } s.serialize_enum_end() } } ////////////////////////////////////////////////////////////////////////////// #[deriving(Clone, PartialEq, Show)] pub enum Token<'a> { Null, Bool(bool), Int(int), I8(i8), I16(i16), I32(i32), I64(i64), Uint(uint), U8(u8), U16(u16), U32(u32), U64(u64), F32(f32), F64(f64), Char(char), Str(&'a str), TupleStart(uint), TupleSep, TupleEnd, StructStart(&'a str, uint), StructSep(&'a str), StructEnd, EnumStart(&'a str, &'a str, uint), EnumSep, EnumEnd, Option(bool), SeqStart(uint), SeqEnd, MapStart(uint), MapEnd, } #[deriving(Show)] enum Error { EndOfStream, SyntaxError, } ////////////////////////////////////////////////////////////////////////////// struct AssertSerializer { iter: Iter, } impl<'a, Iter: Iterator>> AssertSerializer { fn new(iter: Iter) -> AssertSerializer { AssertSerializer { iter: iter, } } fn serialize<'b>(&mut self, token: Token<'b>) -> Result<(), Error> { let t = match self.iter.next() { Some(t) => t, None => { fail!(); } }; assert_eq!(t, token); Ok(()) } } impl<'a, Iter: Iterator>> Serializer for AssertSerializer { fn serialize_null(&mut self) -> Result<(), Error> { self.serialize(Null) } fn serialize_bool(&mut self, v: bool) -> Result<(), Error> { self.serialize(Bool(v)) } fn serialize_int(&mut self, v: int) -> Result<(), Error> { self.serialize(Int(v)) } fn serialize_i8(&mut self, v: i8) -> Result<(), Error> { self.serialize(I8(v)) } fn serialize_i16(&mut self, v: i16) -> Result<(), Error> { self.serialize(I16(v)) } fn serialize_i32(&mut self, v: i32) -> Result<(), Error> { self.serialize(I32(v)) } fn serialize_i64(&mut self, v: i64) -> Result<(), Error> { self.serialize(I64(v)) } fn serialize_uint(&mut self, v: uint) -> Result<(), Error> { self.serialize(Uint(v)) } fn serialize_u8(&mut self, v: u8) -> Result<(), Error> { self.serialize(U8(v)) } fn serialize_u16(&mut self, v: u16) -> Result<(), Error> { self.serialize(U16(v)) } fn serialize_u32(&mut self, v: u32) -> Result<(), Error> { self.serialize(U32(v)) } fn serialize_u64(&mut self, v: u64) -> Result<(), Error> { self.serialize(U64(v)) } fn serialize_f32(&mut self, v: f32) -> Result<(), Error> { self.serialize(F32(v)) } fn serialize_f64(&mut self, v: f64) -> Result<(), Error> { self.serialize(F64(v)) } fn serialize_char(&mut self, v: char) -> Result<(), Error> { self.serialize(Char(v)) } fn serialize_str(&mut self, v: &str) -> Result<(), Error> { self.serialize(Str(v)) } fn serialize_tuple_start(&mut self, len: uint) -> Result<(), Error> { self.serialize(TupleStart(len)) } fn serialize_tuple_sep(&mut self) -> Result<(), Error> { self.serialize(TupleSep) } fn serialize_tuple_end(&mut self) -> Result<(), Error> { self.serialize(TupleEnd) } fn serialize_struct_start(&mut self, name: &str, len: uint) -> Result<(), Error> { self.serialize(StructStart(name, len)) } fn serialize_struct_sep(&mut self, name: &str) -> Result<(), Error> { self.serialize(StructSep(name)) } fn serialize_struct_end(&mut self) -> Result<(), Error> { self.serialize(StructEnd) } fn serialize_enum_start(&mut self, name: &str, variant: &str, len: uint) -> Result<(), Error> { self.serialize(EnumStart(name, variant, len)) } fn serialize_enum_sep(&mut self) -> Result<(), Error> { self.serialize(EnumSep) } fn serialize_enum_end(&mut self) -> Result<(), Error> { self.serialize(EnumEnd) } fn serialize_option< T: Serializable, Error> >(&mut self, v: &Option) -> Result<(), Error> { match *v { Some(ref v) => { try!(self.serialize(Option(true))); v.serialize(self) } None => { self.serialize(Option(false)) } } } fn serialize_seq< T: Serializable, Error>, SeqIter: Iterator >(&mut self, mut iter: SeqIter) -> Result<(), Error> { let (len, _) = iter.size_hint(); try!(self.serialize(SeqStart(len))); for elt in iter { elt.serialize(self).unwrap(); } self.serialize(SeqEnd) } fn serialize_map< K: Serializable, Error>, V: Serializable, Error>, MapIter: Iterator<(K, V)> >(&mut self, mut iter: MapIter) -> Result<(), Error> { let (len, _) = iter.size_hint(); try!(self.serialize(MapStart(len))); for (key, value) in iter { try!(key.serialize(self)); try!(value.serialize(self)); } self.serialize(MapEnd) } } ////////////////////////////////////////////////////////////////////////////// #[test] fn test_tokens_int() { let tokens = vec!( Int(5) ); let mut serializer = AssertSerializer::new(tokens.move_iter()); 5i.serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_str() { let tokens = vec!( Str("a"), ); let mut serializer = AssertSerializer::new(tokens.move_iter()); "a".serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_null() { let tokens = vec!( Null, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); ().serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_option_none() { let tokens = vec!( Option(false), ); let mut serializer = AssertSerializer::new(tokens.move_iter()); None::.serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_option_some() { let tokens = vec!( Option(true), Int(5), ); let mut serializer = AssertSerializer::new(tokens.move_iter()); Some(5).serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_tuple() { let tokens = vec!( TupleStart(2), TupleSep, Int(5), TupleSep, Str("a"), TupleEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); (5, "a").serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_tuple_compound() { let tokens = vec!( TupleStart(3), TupleSep, Null, TupleSep, Null, TupleSep, TupleStart(2), TupleSep, Int(5), TupleSep, Str("a"), TupleEnd, TupleEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); ((), (), (5, "a")).serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_struct_empty() { let tokens = vec!( StructStart("Outer", 1), StructSep("inner"), SeqStart(0), SeqEnd, StructEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); Outer { inner: vec!() }.serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_struct() { let tokens = vec!( StructStart("Outer", 1), StructSep("inner"), SeqStart(1), StructStart("Inner", 3), StructSep("a"), Null, StructSep("b"), Uint(5), StructSep("c"), MapStart(1), Str("abc"), Option(true), Char('c'), MapEnd, StructEnd, SeqEnd, StructEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); let mut map = HashMap::new(); map.insert("abc".to_string(), Some('c')); Outer { inner: vec!( Inner { a: (), b: 5, c: map, }, ) }.serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_enum() { let tokens = vec!( EnumStart("Animal", "Dog", 0), EnumEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); Dog.serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); let tokens = vec!( EnumStart("Animal", "Frog", 2), EnumSep, Str("Henry"), EnumSep, Int(349), EnumEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); Frog("Henry".to_string(), 349).serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_vec_empty() { let tokens = vec!( SeqStart(0), SeqEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); let v: Vec = vec!(); v.serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_vec() { let tokens = vec!( SeqStart(3), Int(5), Int(6), Int(7), SeqEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); (vec!(5, 6, 7)).serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_vec_compound() { let tokens = vec!( SeqStart(3), SeqStart(1), Int(1), SeqEnd, SeqStart(2), Int(2), Int(3), SeqEnd, SeqStart(3), Int(4), Int(5), Int(6), SeqEnd, SeqEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); (vec!(vec!(1), vec!(2, 3), vec!(4, 5, 6))).serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } #[test] fn test_tokens_treemap() { let tokens = vec!( MapStart(2), Int(5), Str("a"), Int(6), Str("b"), MapEnd, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); let mut map = TreeMap::new(); map.insert(5, "a".to_string()); map.insert(6, "b".to_string()); map.serialize(&mut serializer).unwrap(); assert_eq!(serializer.iter.next(), None); } }