diff --git a/serde2/src/bin.rs b/serde2/src/bin.rs index 3c0f6464..d9543dec 100644 --- a/serde2/src/bin.rs +++ b/serde2/src/bin.rs @@ -14,7 +14,7 @@ struct Foo { impl, R> serde2::Serialize for Foo { fn serialize(&self, state: &mut S) -> R { - state.serialize_struct("Foo", FooSerialize { + state.visit_struct("Foo", FooSerialize { value: self, state: 0, }) @@ -31,15 +31,15 @@ impl<'a, S: serde2::VisitorState, R> serde2::Visitor for FooSerialize<' match self.state { 0 => { self.state += 1; - Some(state.serialize_map_elt(true, "x", &self.value.x)) + Some(state.visit_map_elt(true, "x", &self.value.x)) } 1 => { self.state += 1; - Some(state.serialize_map_elt(false, "y", &self.value.y)) + Some(state.visit_map_elt(false, "y", &self.value.y)) } 2 => { self.state += 1; - Some(state.serialize_map_elt(false, "z", &self.value.z)) + Some(state.visit_map_elt(false, "z", &self.value.z)) } _ => { None diff --git a/serde2/src/json/mod.rs b/serde2/src/json/mod.rs new file mode 100644 index 00000000..60bd0789 --- /dev/null +++ b/serde2/src/json/mod.rs @@ -0,0 +1,3 @@ +pub use ser::Serializer; + +pub mod ser; diff --git a/serde2/src/json/ser.rs b/serde2/src/json/ser.rs new file mode 100644 index 00000000..790924b0 --- /dev/null +++ b/serde2/src/json/ser.rs @@ -0,0 +1,208 @@ +use std::io; +use std::num::{FPNaN, FPInfinite}; +use std::f64; + +use super::super::ser as ser; + +/// A structure for implementing serialization to JSON. +pub struct Serializer { + writer: W, +} + +impl Serializer { + /// Creates a new JSON serializer whose output will be written to the writer + /// specified. + pub fn new(writer: W) -> Serializer { + Serializer { + writer: writer, + } + } + + /// Unwrap the Writer from the Serializer. + pub fn unwrap(self) -> W { + self.writer + } +} + +impl ser::VisitorState> for Serializer { + #[inline] + fn visit_null(&mut self) -> io::IoResult<()> { + self.writer.write_str("null") + } + + #[inline] + fn visit_bool(&mut self, value: bool) -> io::IoResult<()> { + if value { + self.writer.write_str("true") + } else { + self.writer.write_str("false") + } + } + + #[inline] + fn visit_i64(&mut self, value: i64) -> io::IoResult<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_u64(&mut self, value: u64) -> io::IoResult<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_f64(&mut self, value: f64) -> io::IoResult<()> { + fmt_f64_or_null(&mut self.writer, value) + } + + #[inline] + fn visit_char(&mut self, v: char) -> io::IoResult<()> { + escape_char(&mut self.writer, v) + } + + #[inline] + fn visit_str(&mut self, value: &'static str) -> io::IoResult<()> { + escape_str(&mut self.writer, value) + } + + fn visit_seq< + T: ser::Serialize, io::IoResult<()>>, + Iter: Iterator + >(&mut self, mut iter: Iter) -> io::IoResult<()> { + try!(write!(self.writer, "[")); + let mut first = true; + for elt in iter { + try!(self.visit_seq_elt(first, elt)); + first = false; + + } + write!(self.writer, "]") + } + + fn visit_seq_elt< + T: ser::Serialize, io::IoResult<()>> + >(&mut self, first: bool, value: T) -> io::IoResult<()> { + if !first { + try!(write!(self.writer, ", ")); + } + + value.serialize(self) + } + + fn visit_tuple< + V: ser::Visitor, io::IoResult<()>> + >(&mut self, mut visitor: V) -> io::IoResult<()> { + try!(write!(self.writer, "[")); + loop { + match visitor.visit(self) { + Some(Ok(())) => { } + Some(Err(err)) => { return Err(err); } + None => { break; } + } + } + write!(self.writer, "]") + } + + fn visit_tuple_struct< + V: ser::Visitor, io::IoResult<()>> + >(&mut self, _name: &'static str, visitor: V) -> io::IoResult<()> { + self.visit_tuple(visitor) + } + + + fn visit_enum< + V: ser::Visitor, io::IoResult<()>> + >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> io::IoResult<()> { + self.visit_tuple(visitor) + } + + fn visit_map< + K: ser::Serialize, io::IoResult<()>>, + V: ser::Serialize, io::IoResult<()>>, + Iter: Iterator<(K, V)> + >(&mut self, mut iter: Iter) -> io::IoResult<()> { + try!(write!(self.writer, "{{")); + let mut first = true; + for (key, value) in iter { + try!(self.visit_map_elt(first, &key, &value)) + first = false; + } + write!(self.writer, "}}") + } + + fn visit_map_elt< + K: ser::Serialize, io::IoResult<()>>, + V: ser::Serialize, io::IoResult<()>> + >(&mut self, first: bool, key: K, value: V) -> io::IoResult<()> { + if !first { + try!(write!(self.writer, ", ")); + } + + try!(key.serialize(self)); + try!(write!(self.writer, ": ")); + value.serialize(self) + } + + fn visit_struct< + V: ser::Visitor, io::IoResult<()>> + >(&mut self, _name: &'static str, mut visitor: V) -> io::IoResult<()> { + try!(write!(self.writer, "{{")); + loop { + match visitor.visit(self) { + Some(Ok(())) => { } + Some(Err(err)) => { return Err(err); } + None => { break; } + } + } + write!(self.writer, "}}") + } +} + +pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> io::IoResult<()> { + try!(wr.write_str("\"")); + + let mut start = 0; + + for (i, byte) in bytes.iter().enumerate() { + let escaped = match *byte { + b'"' => "\\\"", + b'\\' => "\\\\", + b'\x08' => "\\b", + b'\x0c' => "\\f", + b'\n' => "\\n", + b'\r' => "\\r", + b'\t' => "\\t", + _ => { continue; } + }; + + if start < i { + try!(wr.write(bytes.slice(start, i))); + } + + try!(wr.write_str(escaped)); + + start = i + 1; + } + + if start != bytes.len() { + try!(wr.write(bytes.slice_from(start))); + } + + wr.write_str("\"") +} + +pub fn escape_str(wr: &mut W, value: &str) -> io::IoResult<()> { + escape_bytes(wr, value.as_bytes()) +} + +pub fn escape_char(wr: &mut W, value: char) -> io::IoResult<()> { + let mut buf = [0, .. 4]; + value.encode_utf8(buf); + escape_bytes(wr, buf) +} + +fn fmt_f64_or_null(wr: &mut W, value: f64) -> io::IoResult<()> { + match value.classify() { + FPNaN | FPInfinite => wr.write_str("null"), + _ => wr.write_str(f64::to_str_digits(value, 6).as_slice()), + } +} diff --git a/serde2/src/json/value.rs b/serde2/src/json/value.rs new file mode 100644 index 00000000..83c214f5 --- /dev/null +++ b/serde2/src/json/value.rs @@ -0,0 +1,122 @@ +#[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 visit_int(&mut self, value: int) -> Json { + Integer(value) + } + + fn visit_str(&mut self, value: &'static str) -> Json { + String(value.to_string()) + } + + fn visit_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.visit_seq_elt(first, elt)); + first = false; + } + + Array(v) + } + + fn visit_seq_elt< + T: Serialize + >(&mut self, _first: bool, value: T) -> Json { + value.serialize(self) + } + + fn visit_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 visit_tuple_struct< + V: Visitor + >(&mut self, _name: &'static str, visitor: V) -> Json { + self.visit_tuple(visitor) + } + + fn visit_enum< + V: Visitor + >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> Json { + self.visit_tuple(visitor) + } + + fn visit_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.visit_map_elt(first, key, value); + v.insert(self.key.take().unwrap(), value); + first = false; + } + + Object(v) + } + + fn visit_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 visit_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) + } +} diff --git a/serde2/src/lib.rs b/serde2/src/lib.rs index 51a1f917..3cbe1060 100644 --- a/serde2/src/lib.rs +++ b/serde2/src/lib.rs @@ -1,560 +1,7 @@ -use std::io::IoResult; -use std::io; -use std::collections::TreeMap; +pub use ser::{Serialize, Serializer}; +pub use ser::{Visitor, VisitorState}; +pub use ser::FormatState; +pub use ser::GatherTokens; -/////////////////////////////////////////////////////////////////////////////// - -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)) -} +pub mod ser; +//pub mod json; diff --git a/serde2/src/ser.rs b/serde2/src/ser.rs new file mode 100644 index 00000000..575e3686 --- /dev/null +++ b/serde2/src/ser.rs @@ -0,0 +1,490 @@ +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 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: &'static str) -> R; + + fn visit_seq< + V: Visitor + >(&mut self, visitor: V) -> R; + + fn visit_named_seq< + V: Visitor + >(&mut self, _name: &'static str, visitor: V) -> R { + self.visit_seq(visitor) + } + + 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, value: T) -> R; + + fn visit_map< + V: Visitor + >(&mut self, visitor: V) -> R; + + 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, key: K, value: V) -> R; +} + +/////////////////////////////////////////////////////////////////////////////// + +impl, R> Serialize for int { + fn serialize(&self, state: &mut S) -> R { + state.visit_int(*self) + } +} + +impl, R> Serialize for &'static str { + fn serialize(&self, state: &mut S) -> R { + state.visit_str(*self) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +struct IteratorVisitor { + iter: Iter, +} + +impl> IteratorVisitor { + pub fn new(iter: Iter) -> IteratorVisitor { + IteratorVisitor { + iter: iter, + } + } +} + +impl< + T: Serialize, + Iter: Iterator, + S: VisitorState, + R +> Visitor for IteratorVisitor { + fn visit(&mut self, state: &mut S) -> Option { + match self.iter.next() { + Some(value) => Some(state.visit_seq_elt(value)), + None => None + } + } + + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } +} + +/////////////////////////////////////////////////////////////////////////////// + +impl< + S: VisitorState, + R, + T: Serialize +> Serialize for Vec { + fn serialize(&self, state: &mut S) -> R { + state.visit_seq(self.iter()) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +impl< + S: VisitorState, + R, + K: Serialize + Ord, + V: Serialize +> Serialize for TreeMap { + fn serialize(&self, state: &mut S) -> R { + state.visit_map(self.iter()) + } +} + +impl< + 'a, + S: VisitorState, + R, + T0: Serialize, + T1: Serialize +> Serialize for (T0, T1) { + 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> { + 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 + } + } + } + + 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 { + Null, + Bool(bool), + Int(int), + I64(i64), + U64(u64), + F64(f64), + Char(char), + 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 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: &'static str) -> () { + self.serialize(Str(value)) + } + + 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_enum< + V: Visitor + >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> () { + self.visit_seq(visitor) + } + + 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) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +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 visit_null(&mut self) -> IoResult<()> { + write!(self.writer, "()") + } + + fn visit_bool(&mut self, value: bool) -> IoResult<()> { + write!(self.writer, "{}", value) + } + + fn visit_i64(&mut self, value: i64) -> IoResult<()> { + write!(self.writer, "{}", value) + } + + fn visit_u64(&mut self, value: u64) -> IoResult<()> { + write!(self.writer, "{}", value) + } + + fn visit_f64(&mut self, value: f64) -> IoResult<()> { + write!(self.writer, "{}", value) + } + + fn visit_char(&mut self, value: char) -> io::IoResult<()> { + write!(self.writer, "{}", value) + } + + fn visit_str(&mut self, value: &'static str) -> IoResult<()> { + write!(self.writer, "{}", value) + } + + fn visit_seq< + 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 visit_enum< + V: Visitor, IoResult<()>> + >(&mut self, _name: &'static str, _variant: &'static str, visitor: V) -> IoResult<()> { + self.visit_tuple(visitor) + } + + fn visit_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 visit_map< + 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, "}}") + } +} + +/////////////////////////////////////////////////////////////////////////////// + +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)) +}