use std::collections::TreeMap; /////////////////////////////////////////////////////////////////////////////// pub trait Serialize { fn serialize(&self, state: &mut S) -> R; } /////////////////////////////////////////////////////////////////////////////// pub trait Serializer { fn hash>(&self, value: &T) -> R; } /////////////////////////////////////////////////////////////////////////////// pub trait Visitor { fn visit(&mut self, state: &mut S) -> Option; fn size_hint(&self) -> (uint, Option) { (0, None) } } pub trait VisitorState { fn visit_null(&mut self) -> R; fn visit_bool(&mut self, v: bool) -> R; #[inline] fn visit_int(&mut self, v: int) -> R { self.visit_i64(v as i64) } #[inline] fn visit_i8(&mut self, v: i8) -> R { self.visit_i64(v as i64) } #[inline] fn visit_i16(&mut self, v: i16) -> R { self.visit_i64(v as i64) } #[inline] fn visit_i32(&mut self, v: i32) -> R { self.visit_i64(v as i64) } #[inline] fn visit_i64(&mut self, v: i64) -> R; #[inline] fn visit_uint(&mut self, v: uint) -> R { self.visit_u64(v as u64) } #[inline] fn visit_u8(&mut self, v: u8) -> R { self.visit_u64(v as u64) } #[inline] fn visit_u16(&mut self, v: u16) -> R { self.visit_u64(v as u64) } #[inline] fn visit_u32(&mut self, v: u32) -> R { self.visit_u64(v as u64) } #[inline] fn visit_u64(&mut self, v: u64) -> R; #[inline] fn visit_f32(&mut self, v: f32) -> R { self.visit_f64(v as f64) } fn visit_f64(&mut self, v: f64) -> R; fn visit_char(&mut self, value: char) -> R; fn visit_str(&mut self, value: &str) -> R; fn visit_seq< V: Visitor >(&mut self, visitor: V) -> R; #[inline] fn visit_named_seq< V: Visitor >(&mut self, _name: &'static str, visitor: V) -> R { self.visit_seq(visitor) } #[inline] fn visit_enum< V: Visitor >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> R { self.visit_seq(visitor) } fn visit_seq_elt< T: Serialize >(&mut self, first: bool, value: T) -> R; fn visit_map< V: Visitor >(&mut self, visitor: V) -> R; #[inline] fn visit_named_map< V: Visitor >(&mut self, _name: &'static str, visitor: V) -> R { self.visit_map(visitor) } fn visit_map_elt< K: Serialize, V: Serialize >(&mut self, first: bool, key: K, value: V) -> R; } /////////////////////////////////////////////////////////////////////////////// macro_rules! impl_serialize { ($ty:ty, $method:ident) => { impl, R> Serialize for $ty { #[inline] fn serialize(&self, state: &mut S) -> R { state.$method(*self) } } } } impl_serialize!(bool, visit_bool) impl_serialize!(int, visit_int) impl_serialize!(i8, visit_i8) impl_serialize!(i16, visit_i16) impl_serialize!(i32, visit_i32) impl_serialize!(i64, visit_i64) impl_serialize!(uint, visit_uint) impl_serialize!(u8, visit_u8) impl_serialize!(u16, visit_u16) impl_serialize!(u32, visit_u32) impl_serialize!(u64, visit_u64) impl_serialize!(f32, visit_f32) impl_serialize!(f64, visit_f64) impl_serialize!(char, visit_char) /////////////////////////////////////////////////////////////////////////////// impl<'a, S: VisitorState, R> Serialize for &'a str { #[inline] fn serialize(&self, s: &mut S) -> R { s.visit_str(*self) } } impl, R> Serialize for String { #[inline] fn serialize(&self, s: &mut S) -> R { s.visit_str(self.as_slice()) } } /////////////////////////////////////////////////////////////////////////////// pub struct SeqIteratorVisitor { iter: Iter, first: bool, } impl> SeqIteratorVisitor { #[inline] pub fn new(iter: Iter) -> SeqIteratorVisitor { SeqIteratorVisitor { iter: iter, first: true, } } } impl< T: Serialize, Iter: Iterator, S: VisitorState, R > Visitor for SeqIteratorVisitor { #[inline] fn visit(&mut self, state: &mut S) -> Option { let first = self.first; self.first = false; match self.iter.next() { Some(value) => Some(state.visit_seq_elt(first, value)), None => None } } #[inline] fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } /////////////////////////////////////////////////////////////////////////////// impl< S: VisitorState, R, T: Serialize > Serialize for Vec { #[inline] fn serialize(&self, state: &mut S) -> R { state.visit_seq(SeqIteratorVisitor::new(self.iter())) } } /////////////////////////////////////////////////////////////////////////////// pub struct MapIteratorVisitor { iter: Iter, first: bool, } impl> MapIteratorVisitor { #[inline] pub fn new(iter: Iter) -> MapIteratorVisitor { MapIteratorVisitor { iter: iter, first: true, } } } impl< K: Serialize, V: Serialize, Iter: Iterator<(K, V)>, S: VisitorState, R > Visitor for MapIteratorVisitor { #[inline] fn visit(&mut self, state: &mut S) -> Option { let first = self.first; self.first = false; match self.iter.next() { Some((key, value)) => Some(state.visit_map_elt(first, key, value)), None => None } } #[inline] fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } /////////////////////////////////////////////////////////////////////////////// impl< S: VisitorState, R, K: Serialize + Ord, V: Serialize > Serialize for TreeMap { #[inline] fn serialize(&self, state: &mut S) -> R { state.visit_map(MapIteratorVisitor::new(self.iter())) } } impl< 'a, S: VisitorState, R, T0: Serialize, T1: Serialize > Serialize for (T0, T1) { #[inline] fn serialize(&self, state: &mut S) -> R { state.visit_seq(Tuple2Serialize { value: self, state: 0 }) } } struct Tuple2Serialize<'a, T0, T1> { value: &'a (T0, T1), state: uint, } impl< 'a, S: VisitorState, R, T0: Serialize, T1: Serialize > Visitor for Tuple2Serialize<'a, T0, T1> { #[inline] fn visit(&mut self, state: &mut S) -> Option { match self.state { 0 => { self.state += 1; let (ref value, _) = *self.value; Some(state.visit_seq_elt(true, value)) } 1 => { self.state += 1; let (_, ref value) = *self.value; Some(state.visit_seq_elt(false, value)) } _ => { None } } } #[inline] fn size_hint(&self) -> (uint, Option) { let size = 2 - self.state; (size, Some(size)) } } impl< 'a, S: VisitorState, R, T: Serialize > Serialize for &'a T { #[inline] fn serialize(&self, state: &mut S) -> R { (**self).serialize(state) } } /////////////////////////////////////////////////////////////////////////////// #[deriving(Show)] pub enum Token<'a> { Null, Bool(bool), Int(int), I64(i64), U64(u64), F64(f64), Char(char), Str(&'a str), String(String), SeqStart(uint), MapStart(uint), StructStart(&'static str, uint), End, } pub trait TokenState<'a, R>: VisitorState { fn serialize(&mut self, token: Token<'a>) -> R; } /////////////////////////////////////////////////////////////////////////////// pub struct GatherTokens<'a> { tokens: Vec>, } impl<'a> GatherTokens<'a> { pub fn new() -> GatherTokens<'a> { GatherTokens { tokens: Vec::new(), } } pub fn unwrap(self) -> Vec> { self.tokens } } impl<'a> TokenState<'a, ()> for GatherTokens<'a> { fn serialize(&mut self, token: Token<'a>) -> () { self.tokens.push(token); } } impl<'a> VisitorState<()> for GatherTokens<'a> { fn visit_null(&mut self) -> () { self.serialize(Null) } fn visit_bool(&mut self, value: bool) -> () { self.serialize(Bool(value)) } fn visit_i64(&mut self, value: i64) -> () { self.serialize(I64(value)) } fn visit_u64(&mut self, value: u64) -> () { self.serialize(U64(value)) } fn visit_f64(&mut self, value: f64) -> () { self.serialize(F64(value)) } fn visit_char(&mut self, value: char) -> () { self.serialize(Char(value)) } fn visit_str(&mut self, value: &str) -> () { self.serialize(String(value.to_string())) } fn visit_seq< V: Visitor, ()> >(&mut self, mut visitor: V) -> () { let (len, _) = visitor.size_hint(); self.tokens.push(SeqStart(len)); loop { match visitor.visit(self) { Some(()) => { } None => { break; } } } self.tokens.push(End) } fn visit_seq_elt< T: Serialize, ()> >(&mut self, _first: bool, value: T) -> () { value.serialize(self) } fn visit_map< V: Visitor, ()> >(&mut self, mut visitor: V) -> () { let (len, _) = visitor.size_hint(); self.serialize(MapStart(len)); loop { match visitor.visit(self) { Some(()) => { } None => { break; } } } self.serialize(End) } fn visit_named_map< V: Visitor, ()> >(&mut self, name: &'static str, mut visitor: V) -> () { let (len, _) = visitor.size_hint(); self.serialize(StructStart(name, len)); loop { match visitor.visit(self) { Some(()) => { } None => { break; } } } self.serialize(End) } fn visit_map_elt< K: Serialize, ()>, V: Serialize, ()> >(&mut self, _first: bool, key: K, value: V) -> () { key.serialize(self); value.serialize(self) } }