use std::io::IoResult; use std::io; 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 serialize_int(&mut self, value: int) -> R; fn serialize_str(&mut self, value: &'static str) -> R; fn serialize_seq< T: Serialize, Iter: Iterator >(&mut self, iter: Iter) -> R; fn serialize_seq_elt< T: Serialize >(&mut self, first: bool, value: T) -> R; fn serialize_tuple< V: Visitor >(&mut self, visitor: V) -> R; fn serialize_tuple_struct< V: Visitor >(&mut self, name: &'static str, mut visitor: V) -> R; fn serialize_enum< V: Visitor >(&mut self, name: &'static str, variant: &'static str, visitor: V) -> R; fn serialize_map< K: Serialize, V: Serialize, Iter: Iterator<(K, V)> >(&mut self, iter: Iter) -> R; fn serialize_map_elt< K: Serialize, V: Serialize >(&mut self, first: bool, key: K, value: V) -> R; fn serialize_struct< V: Visitor >(&mut self, name: &'static str, visitor: V) -> R; } /////////////////////////////////////////////////////////////////////////////// impl, R> Serialize for int { fn serialize(&self, state: &mut S) -> R { state.serialize_int(*self) } } impl, R> Serialize for &'static str { fn serialize(&self, state: &mut S) -> R { state.serialize_str(*self) } } impl< S: VisitorState, R, T: Serialize > Serialize for Vec { fn serialize(&self, state: &mut S) -> R { state.serialize_seq(self.iter()) } } impl< S: VisitorState, R, K: Serialize + Ord, V: Serialize > Serialize for TreeMap { fn serialize(&self, state: &mut S) -> R { state.serialize_map(self.iter()) } } impl< 'a, S: VisitorState, R, T0: Serialize, T1: Serialize > Serialize for (T0, T1) { fn serialize(&self, state: &mut S) -> R { state.serialize_tuple(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> { fn visit(&mut self, state: &mut S) -> Option { match self.state { 0 => { self.state += 1; let (ref value, _) = *self.value; Some(state.serialize_seq_elt(true, value)) } 1 => { self.state += 1; let (_, ref value) = *self.value; Some(state.serialize_seq_elt(false, value)) } _ => { None } } } 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 { fn serialize(&self, state: &mut S) -> R { (**self).serialize(state) } } /////////////////////////////////////////////////////////////////////////////// #[deriving(Show)] pub enum Token { Int(int), Str(&'static str), SeqStart(uint), MapStart(uint), StructStart(&'static str, uint), End, } pub trait TokenState: VisitorState { fn serialize(&mut self, token: Token) -> R; } /////////////////////////////////////////////////////////////////////////////// pub struct GatherTokens { tokens: Vec, } impl GatherTokens { pub fn new() -> GatherTokens { GatherTokens { tokens: Vec::new(), } } pub fn unwrap(self) -> Vec { self.tokens } } impl TokenState<()> for GatherTokens { fn serialize(&mut self, token: Token) -> () { self.tokens.push(token); } } impl VisitorState<()> for GatherTokens { fn serialize_int(&mut self, value: int) -> () { self.serialize(Int(value)) } fn serialize_str(&mut self, value: &'static str) -> () { self.serialize(Str(value)) } fn serialize_seq< T: Serialize, Iter: Iterator >(&mut self, mut iter: Iter) -> () { let (len, _) = iter.size_hint(); self.serialize(SeqStart(len)); let mut first = false; for elt in iter { self.serialize_seq_elt(first, elt); if first { first = false; } } self.serialize(End) } fn serialize_seq_elt< T: Serialize >(&mut self, _first: bool, value: T) -> () { value.serialize(self); } fn serialize_tuple< 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 serialize_tuple_struct< V: Visitor >(&mut self, _name: &'static str, visitor: V) -> () { self.serialize_tuple(visitor) } fn serialize_enum< V: Visitor >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> () { self.serialize_tuple(visitor) } fn serialize_map< K: Serialize, V: Serialize, Iter: Iterator<(K, V)> >(&mut self, mut iter: Iter) -> () { let (len, _) = iter.size_hint(); self.serialize(MapStart(len)); let mut first = true; for (key, value) in iter { self.serialize_map_elt(first, key, value); first = false; } self.serialize(End) } fn serialize_map_elt< K: Serialize, V: Serialize >(&mut self, _first: bool, key: K, value: V) -> () { key.serialize(self); value.serialize(self); } fn serialize_struct< 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) } } /////////////////////////////////////////////////////////////////////////////// pub struct FormatState { writer: W, } impl FormatState { pub fn new(writer: W) -> FormatState { FormatState { writer: writer, } } pub fn unwrap(self) -> W { self.writer } } impl VisitorState> for FormatState { fn serialize_int(&mut self, value: int) -> IoResult<()> { write!(self.writer, "{}", value) } fn serialize_str(&mut self, value: &'static str) -> IoResult<()> { write!(self.writer, "{}", value) } fn serialize_seq< T: Serialize, IoResult<()>>, Iter: Iterator >(&mut self, mut iter: Iter) -> IoResult<()> { try!(write!(self.writer, "[")); let mut first = true; for elt in iter { try!(self.serialize_seq_elt(first, elt)); first = false; } write!(self.writer, "]") } fn serialize_seq_elt< T: Serialize, IoResult<()>> >(&mut self, first: bool, value: T) -> IoResult<()> { if !first { try!(write!(self.writer, ", ")); } value.serialize(self) } fn serialize_tuple< V: Visitor, IoResult<()>> >(&mut self, mut visitor: V) -> IoResult<()> { try!(write!(self.writer, "[")); loop { match visitor.visit(self) { Some(Ok(())) => { } Some(Err(err)) => { return Err(err); } None => { break; } } } write!(self.writer, "]") } fn serialize_tuple_struct< V: Visitor, IoResult<()>> >(&mut self, _name: &'static str, visitor: V) -> IoResult<()> { self.serialize_tuple(visitor) } fn serialize_enum< V: Visitor, IoResult<()>> >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> IoResult<()> { self.serialize_tuple(visitor) } fn serialize_map< K: Serialize, IoResult<()>>, V: Serialize, IoResult<()>>, Iter: Iterator<(K, V)> >(&mut self, mut iter: Iter) -> IoResult<()> { try!(write!(self.writer, "{{")); let mut first = true; for (key, value) in iter { try!(self.serialize_map_elt(first, &key, &value)) first = false; } write!(self.writer, "}}") } fn serialize_map_elt< K: Serialize, IoResult<()>>, V: Serialize, IoResult<()>> >(&mut self, first: bool, key: K, value: V) -> IoResult<()> { if !first { try!(write!(self.writer, ", ")); } try!(key.serialize(self)); try!(write!(self.writer, ": ")); value.serialize(self) } fn serialize_struct< V: Visitor, IoResult<()>> >(&mut self, _name: &'static str, mut visitor: V) -> IoResult<()> { try!(write!(self.writer, "{{")); loop { match visitor.visit(self) { Some(Ok(())) => { } Some(Err(err)) => { return Err(err); } None => { break; } } } write!(self.writer, "}}") } } /////////////////////////////////////////////////////////////////////////////// #[deriving(PartialEq)] pub enum Json { Integer(int), String(String), Array(Vec), Object(TreeMap), } pub struct JsonSerializer { key: Option } impl JsonSerializer { pub fn new() -> JsonSerializer { JsonSerializer { key: None } } } impl VisitorState for JsonSerializer { fn serialize_int(&mut self, value: int) -> Json { Integer(value) } fn serialize_str(&mut self, value: &'static str) -> Json { String(value.to_string()) } fn serialize_seq< T: Serialize, Iter: Iterator >(&mut self, mut iter: Iter) -> Json { let (len, _) = iter.size_hint(); let mut v = Vec::with_capacity(len); let mut first = true; for elt in iter { v.push(self.serialize_seq_elt(first, elt)); first = false; } Array(v) } fn serialize_seq_elt< T: Serialize >(&mut self, _first: bool, value: T) -> Json { value.serialize(self) } fn serialize_tuple< V: Visitor >(&mut self, mut visitor: V) -> Json { let (len, _) = visitor.size_hint(); let mut v = Vec::with_capacity(len); loop { match visitor.visit(self) { Some(value) => { v.push(value); } None => { break; } } } Array(v) } fn serialize_tuple_struct< V: Visitor >(&mut self, _name: &'static str, visitor: V) -> Json { self.serialize_tuple(visitor) } fn serialize_enum< V: Visitor >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> Json { self.serialize_tuple(visitor) } fn serialize_map< K: Serialize, V: Serialize, Iter: Iterator<(K, V)> >(&mut self, mut iter: Iter) -> Json { let mut v = TreeMap::new(); let mut first = true; for (key, value) in iter { let value = self.serialize_map_elt(first, key, value); v.insert(self.key.take().unwrap(), value); first = false; } Object(v) } fn serialize_map_elt< K: Serialize, V: Serialize >(&mut self, _first: bool, key: K, value: V) -> Json { match key.serialize(self) { String(key) => { self.key = Some(key); } _ => { fail!() } } value.serialize(self) } fn serialize_struct< V: Visitor >(&mut self, _name: &'static str, mut visitor: V) -> Json { let mut v = TreeMap::new(); loop { match visitor.visit(self) { Some(value) => { v.insert(self.key.take().unwrap(), value); } None => { break; } } } Object(v) } } /////////////////////////////////////////////////////////////////////////////// pub fn to_format_vec< T: Serialize, IoResult<()>> >(value: &T) -> IoResult> { let writer = io::MemWriter::new(); let mut state = FormatState::new(writer); try!(value.serialize(&mut state)); Ok(state.unwrap().unwrap()) } pub fn to_format_string< T: Serialize, IoResult<()>> >(value: &T) -> IoResult>> { let vec = try!(to_format_vec(value)); Ok(String::from_utf8(vec)) }