diff --git a/benches/bench_log.rs b/benches/bench_log.rs index 7929c031..8433be0b 100644 --- a/benches/bench_log.rs +++ b/benches/bench_log.rs @@ -13,6 +13,7 @@ use std::io::{MemWriter, AsRefWriter}; use test::Bencher; use serde::de; +use serde::json::ser::escape_str; use serde::json; use serde::ser::Serialize; use serde::ser; @@ -729,106 +730,106 @@ fn manual_no_escape(mut wr: W, log: &Log) { fn manual_escape(mut wr: W, log: &Log) { wr.write_str("{").unwrap(); - json::escape_str(&mut wr, "timestamp").unwrap(); + escape_str(&mut wr, "timestamp").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.timestamp)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "zone_id").unwrap(); + escape_str(&mut wr, "zone_id").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.zone_id)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "zone_plan").unwrap(); + escape_str(&mut wr, "zone_plan").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.zone_plan as int)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "http").unwrap(); + escape_str(&mut wr, "http").unwrap(); wr.write_str(":{").unwrap(); - json::escape_str(&mut wr, "protocol").unwrap(); + escape_str(&mut wr, "protocol").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.http.protocol as uint)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "status").unwrap(); + escape_str(&mut wr, "status").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.http.status)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "host_status").unwrap(); + escape_str(&mut wr, "host_status").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.http.host_status)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "up_status").unwrap(); + escape_str(&mut wr, "up_status").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.http.up_status)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "method").unwrap(); + escape_str(&mut wr, "method").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.http.method as uint)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "content_type").unwrap(); + escape_str(&mut wr, "content_type").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.http.content_type.as_slice()).unwrap(); + escape_str(&mut wr, log.http.content_type.as_slice()).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "user_agent").unwrap(); + escape_str(&mut wr, "user_agent").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.http.user_agent.as_slice()).unwrap(); + escape_str(&mut wr, log.http.user_agent.as_slice()).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "referer").unwrap(); + escape_str(&mut wr, "referer").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.http.referer.as_slice()).unwrap(); + escape_str(&mut wr, log.http.referer.as_slice()).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "request_uri").unwrap(); + escape_str(&mut wr, "request_uri").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.http.request_uri.as_slice()).unwrap(); + escape_str(&mut wr, log.http.request_uri.as_slice()).unwrap(); wr.write_str("},").unwrap(); - json::escape_str(&mut wr, "origin").unwrap(); + escape_str(&mut wr, "origin").unwrap(); wr.write_str(":{").unwrap(); - json::escape_str(&mut wr, "ip").unwrap(); + escape_str(&mut wr, "ip").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.origin.ip.as_slice()).unwrap(); + escape_str(&mut wr, log.origin.ip.as_slice()).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "port").unwrap(); + escape_str(&mut wr, "port").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.origin.port)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "hostname").unwrap(); + escape_str(&mut wr, "hostname").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.origin.hostname.as_slice()).unwrap(); + escape_str(&mut wr, log.origin.hostname.as_slice()).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "protocol").unwrap(); + escape_str(&mut wr, "protocol").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.origin.protocol as uint)).unwrap(); wr.write_str("},").unwrap(); - json::escape_str(&mut wr, "country").unwrap(); + escape_str(&mut wr, "country").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.country as uint)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "cache_status").unwrap(); + escape_str(&mut wr, "cache_status").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.cache_status as uint)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "server_ip").unwrap(); + escape_str(&mut wr, "server_ip").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.server_ip.as_slice()).unwrap(); + escape_str(&mut wr, log.server_ip.as_slice()).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "server_name").unwrap(); + escape_str(&mut wr, "server_name").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.server_name.as_slice()).unwrap(); + escape_str(&mut wr, log.server_name.as_slice()).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "remote_ip").unwrap(); + escape_str(&mut wr, "remote_ip").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.remote_ip.as_slice()).unwrap(); + escape_str(&mut wr, log.remote_ip.as_slice()).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "bytes_dlv").unwrap(); + escape_str(&mut wr, "bytes_dlv").unwrap(); wr.write_str(":").unwrap(); (write!(wr, "{}", log.bytes_dlv)).unwrap(); wr.write_str(",").unwrap(); - json::escape_str(&mut wr, "ray_id").unwrap(); + escape_str(&mut wr, "ray_id").unwrap(); wr.write_str(":").unwrap(); - json::escape_str(&mut wr, log.ray_id.as_slice()).unwrap(); + escape_str(&mut wr, log.ray_id.as_slice()).unwrap(); wr.write_str("}").unwrap(); } diff --git a/src/json/mod.rs b/src/json/mod.rs index a03e12bc..33da2f34 100644 --- a/src/json/mod.rs +++ b/src/json/mod.rs @@ -294,12 +294,8 @@ fn main() { use std::char; use std::error; -use std::f32; -use std::f64; use std::fmt; -use std::io::{IoResult, MemWriter}; use std::io; -use std::num::{FPNaN, FPInfinite}; use std::num; use std::str::ScalarValue; use std::str; @@ -307,14 +303,24 @@ use std::string; use std::vec::Vec; use de; -use ser::Serialize; -use ser; +pub use self::ser::{ + Serializer, + PrettySerializer, + to_writer, + to_vec, + to_string, + to_pretty_writer, + to_pretty_vec, + to_pretty_string, +}; pub use self::value::{Value, ToJson}; pub use self::builder::{ListBuilder, ObjectBuilder}; pub mod builder; pub mod value; +pub mod ser; + /// The failed expectation of InvalidSyntax #[deriving(Clone, PartialEq, Show)] @@ -435,642 +441,6 @@ impl error::FromError for Error { } } -/* -#[deriving(Clone, Eq, Show)] -pub enum DecoderError { - ParseError(Error), - ExpectedError(String, String), - MissingFieldError(String), - UnknownVariantError(String), -} -*/ - - -pub type SerializeResult = io::IoResult<()>; - -pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> 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, v: &str) -> IoResult<()> { - escape_bytes(wr, v.as_bytes()) -} - -pub fn escape_char(wr: &mut W, v: char) -> IoResult<()> { - let mut buf = [0, .. 4]; - v.encode_utf8(buf); - escape_bytes(wr, buf) -} - -fn fmt_f32_or_null(wr: &mut W, v: f32) -> IoResult<()> { - match v.classify() { - FPNaN | FPInfinite => wr.write_str("null"), - _ => wr.write_str(f32::to_str_digits(v, 6).as_slice()), - } -} - -fn fmt_f64_or_null(wr: &mut W, v: f64) -> IoResult<()> { - match v.classify() { - FPNaN | FPInfinite => wr.write_str("null"), - _ => wr.write_str(f64::to_str_digits(v, 6).as_slice()), - } -} - -fn spaces(wr: &mut W, mut n: uint) -> IoResult<()> { - const LEN: uint = 16; - const BUF: [u8, ..LEN] = [b' ', ..LEN]; - - while n >= LEN { - try!(wr.write(BUF)); - n -= LEN; - } - - if n > 0 { - wr.write(BUF.slice_to(n)) - } else { - Ok(()) - } -} - -/* -#[deriving(Show)] -enum SerializerState { - ValueState, - TupleState, - StructState, - EnumState, -} -*/ - -/// A structure for implementing serialization to JSON. -pub struct Serializer { - wr: W, - first: bool, -} - -impl Serializer { - /// Creates a new JSON serializer whose output will be written to the writer - /// specified. - pub fn new(wr: W) -> Serializer { - Serializer { - wr: wr, - first: true, - } - } - - /// Unwrap the Writer from the Serializer. - pub fn unwrap(self) -> W { - self.wr - } -} - -impl ser::Serializer for Serializer { - #[inline] - fn serialize_null(&mut self) -> IoResult<()> { - self.wr.write_str("null") - } - - #[inline] - fn serialize_bool(&mut self, v: bool) -> IoResult<()> { - if v { - self.wr.write_str("true") - } else { - self.wr.write_str("false") - } - } - - #[inline] - fn serialize_int(&mut self, v: int) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_i8(&mut self, v: i8) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_i16(&mut self, v: i16) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_i32(&mut self, v: i32) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_i64(&mut self, v: i64) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_uint(&mut self, v: uint) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_u8(&mut self, v: u8) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_u16(&mut self, v: u16) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_u32(&mut self, v: u32) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_u64(&mut self, v: u64) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_f32(&mut self, v: f32) -> IoResult<()> { - fmt_f32_or_null(&mut self.wr, v) - } - - #[inline] - fn serialize_f64(&mut self, v: f64) -> IoResult<()> { - fmt_f64_or_null(&mut self.wr, v) - } - - #[inline] - fn serialize_char(&mut self, v: char) -> IoResult<()> { - escape_char(&mut self.wr, v) - } - - #[inline] - fn serialize_str(&mut self, v: &str) -> IoResult<()> { - escape_str(&mut self.wr, v) - } - - #[inline] - fn serialize_tuple_start(&mut self, _len: uint) -> IoResult<()> { - self.first = true; - self.wr.write_str("[") - } - - #[inline] - fn serialize_tuple_elt< - T: Serialize, io::IoError> - >(&mut self, value: &T) -> IoResult<()> { - if self.first { - self.first = false; - } else { - try!(self.wr.write_str(",")); - } - value.serialize(self) - } - - #[inline] - fn serialize_tuple_end(&mut self) -> IoResult<()> { - self.wr.write_str("]") - } - - #[inline] - fn serialize_struct_start(&mut self, _name: &str, _len: uint) -> IoResult<()> { - self.first = true; - self.wr.write_str("{") - } - - #[inline] - fn serialize_struct_elt< - T: Serialize, io::IoError> - >(&mut self, name: &str, value: &T) -> IoResult<()> { - if self.first { - self.first = false; - } else { - try!(self.wr.write_str(",")); - } - try!(name.serialize(self)); - try!(self.wr.write_str(":")); - value.serialize(self) - } - - #[inline] - fn serialize_struct_end(&mut self) -> IoResult<()> { - self.wr.write_str("}") - } - - #[inline] - fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: uint) -> IoResult<()> { - self.first = true; - try!(self.wr.write_str("{")); - try!(self.serialize_str(variant)); - self.wr.write_str(":[") - } - - #[inline] - fn serialize_enum_elt< - T: Serialize, io::IoError> - >(&mut self, value: &T) -> IoResult<()> { - if self.first { - self.first = false; - } else { - try!(self.wr.write_str(",")); - } - value.serialize(self) - } - - #[inline] - fn serialize_enum_end(&mut self) -> IoResult<()> { - self.wr.write_str("]}") - } - - #[inline] - fn serialize_option< - T: Serialize, io::IoError> - >(&mut self, v: &Option) -> IoResult<()> { - match *v { - Some(ref v) => { - v.serialize(self) - } - None => { - self.serialize_null() - } - } - } - - #[inline] - fn serialize_seq< - T: Serialize, io::IoError>, - Iter: Iterator - >(&mut self, mut iter: Iter) -> IoResult<()> { - try!(self.wr.write_str("[")); - let mut first = true; - for elt in iter { - if first { - first = false; - } else { - try!(self.wr.write_str(",")); - } - try!(elt.serialize(self)); - - } - self.wr.write_str("]") - } - - #[inline] - fn serialize_map< - K: Serialize, io::IoError>, - V: Serialize, io::IoError>, - Iter: Iterator<(K, V)> - >(&mut self, mut iter: Iter) -> IoResult<()> { - try!(self.wr.write_str("{")); - let mut first = true; - for (key, value) in iter { - if first { - first = false; - } else { - try!(self.wr.write_str(",")); - } - try!(key.serialize(self)); - try!(self.wr.write_str(":")); - try!(value.serialize(self)); - } - self.wr.write_str("}") - } -} - -/// Another serializer for JSON, but prints out human-readable JSON instead of -/// compact data -pub struct PrettySerializer { - wr: W, - indent: uint, - first: bool, -} - -impl PrettySerializer { - /// Creates a new serializer whose output will be written to the specified writer - pub fn new(wr: W) -> PrettySerializer { - PrettySerializer { - wr: wr, - indent: 0, - first: true, - } - } - - /// Unwrap the Writer from the Serializer. - pub fn unwrap(self) -> W { - self.wr - } - - #[inline] - fn serialize_sep(&mut self) -> IoResult<()> { - if self.first { - self.first = false; - self.indent += 2; - try!(self.wr.write_str("\n")); - } else { - try!(self.wr.write_str(",\n")); - } - - spaces(&mut self.wr, self.indent) - } - - #[inline] - fn serialize_end(&mut self, s: &str) -> IoResult<()> { - if !self.first { - try!(self.wr.write_str("\n")); - self.indent -= 2; - try!(spaces(&mut self.wr, self.indent)); - } - - self.first = false; - - self.wr.write_str(s) - } -} - -impl ser::Serializer for PrettySerializer { - #[inline] - fn serialize_null(&mut self) -> IoResult<()> { - self.wr.write_str("null") - } - - #[inline] - fn serialize_bool(&mut self, v: bool) -> IoResult<()> { - if v { - self.wr.write_str("true") - } else { - self.wr.write_str("false") - } - } - - #[inline] - fn serialize_int(&mut self, v: int) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_i8(&mut self, v: i8) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_i16(&mut self, v: i16) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_i32(&mut self, v: i32) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_i64(&mut self, v: i64) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_uint(&mut self, v: uint) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_u8(&mut self, v: u8) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_u16(&mut self, v: u16) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_u32(&mut self, v: u32) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_u64(&mut self, v: u64) -> IoResult<()> { - write!(self.wr, "{}", v) - } - - #[inline] - fn serialize_f32(&mut self, v: f32) -> IoResult<()> { - fmt_f32_or_null(&mut self.wr, v) - } - - #[inline] - fn serialize_f64(&mut self, v: f64) -> IoResult<()> { - fmt_f64_or_null(&mut self.wr, v) - } - - #[inline] - fn serialize_char(&mut self, v: char) -> IoResult<()> { - escape_char(&mut self.wr, v) - } - - #[inline] - fn serialize_str(&mut self, v: &str) -> IoResult<()> { - escape_str(&mut self.wr, v) - } - - #[inline] - fn serialize_tuple_start(&mut self, _len: uint) -> IoResult<()> { - self.first = true; - self.wr.write_str("[") - } - - #[inline] - fn serialize_tuple_elt< - T: Serialize, io::IoError> - >(&mut self, value: &T) -> IoResult<()> { - try!(self.serialize_sep()); - value.serialize(self) - } - - #[inline] - fn serialize_tuple_end(&mut self) -> IoResult<()> { - self.serialize_end("]") - } - - #[inline] - fn serialize_struct_start(&mut self, _name: &str, _len: uint) -> IoResult<()> { - self.first = true; - self.wr.write_str("{") - } - - #[inline] - fn serialize_struct_elt< - T: Serialize, io::IoError> - >(&mut self, name: &str, value: &T) -> IoResult<()> { - try!(self.serialize_sep()); - try!(self.serialize_str(name)); - try!(self.wr.write_str(": ")); - value.serialize(self) - } - - #[inline] - fn serialize_struct_end(&mut self) -> IoResult<()> { - self.serialize_end("}") - } - - #[inline] - fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: uint) -> IoResult<()> { - self.first = true; - try!(self.wr.write_str("{")); - try!(self.serialize_sep()); - try!(self.serialize_str(variant)); - self.first = true; - self.wr.write_str(": [") - } - - #[inline] - fn serialize_enum_elt< - T: Serialize, io::IoError> - >(&mut self, value: &T) -> IoResult<()> { - try!(self.serialize_sep()); - value.serialize(self) - } - - #[inline] - fn serialize_enum_end(&mut self) -> IoResult<()> { - try!(self.serialize_tuple_end()); - self.serialize_struct_end() - } - - #[inline] - fn serialize_option< - T: Serialize, io::IoError> - >(&mut self, v: &Option) -> IoResult<()> { - match *v { - Some(ref v) => { - v.serialize(self) - } - None => { - self.serialize_null() - } - } - } - - #[inline] - fn serialize_seq< - T: Serialize, io::IoError>, - Iter: Iterator - >(&mut self, mut iter: Iter) -> IoResult<()> { - try!(self.wr.write_str("[")); - - self.first = true; - for elt in iter { - try!(self.serialize_sep()); - try!(elt.serialize(self)); - } - - self.serialize_end("]") - } - - #[inline] - fn serialize_map< - K: Serialize, io::IoError>, - V: Serialize, io::IoError>, - Iter: Iterator<(K, V)> - >(&mut self, mut iter: Iter) -> IoResult<()> { - try!(self.wr.write_str("{")); - - self.first = true; - for (key, value) in iter { - try!(self.serialize_sep()); - try!(key.serialize(self)); - try!(self.wr.write_str(": ")); - try!(value.serialize(self)); - } - - self.serialize_end("}") - } -} - -/// Encode the specified struct into a json `[u8]` buffer. -#[inline] -pub fn to_vec< - T: ser::Serialize, io::IoError> ->(value: &T) -> Vec { - let wr = MemWriter::with_capacity(1024); - let mut serializer = Serializer::new(wr); - // We are writing to a MemWriter, which doesn't fail. So we can ignore - // the error. - value.serialize(&mut serializer).unwrap(); - serializer.unwrap().unwrap() -} - -/// Encode the specified struct into a json `String` buffer. -#[inline] -pub fn to_string< - T: ser::Serialize, io::IoError> ->(value: &T) -> Result> { - let buf = to_vec(value); - string::String::from_utf8(buf) -} - -/// Encode the specified struct into a json `[u8]` buffer. -pub fn to_pretty_vec< - T: ser::Serialize, io::IoError> ->(value: &T) -> Vec { - let wr = MemWriter::new(); - let mut serializer = PrettySerializer::new(wr); - value.serialize(&mut serializer).unwrap(); - serializer.unwrap().unwrap() -} - -/// Encode the specified struct into a json `String` buffer. -pub fn to_pretty_string< - T: ser::Serialize, io::IoError> ->(value: &T) -> Result> { - let buf = to_pretty_vec(value); - string::String::from_utf8(buf) -} - -/* -/// The output of the streaming parser. -#[deriving(Eq, Clone, Show)] -pub enum JsonEvent { - ObjectStart, - ObjectEnd, - ListStart, - ListEnd, - BooleanValue(bool), - NumberValue(f64), - StringValue(String), - NullValue, - Error(Error), -} -*/ - #[deriving(PartialEq, Show)] enum ParserState { // Parse a value. diff --git a/src/json/ser.rs b/src/json/ser.rs new file mode 100644 index 00000000..f45c77ef --- /dev/null +++ b/src/json/ser.rs @@ -0,0 +1,634 @@ +use std::f32; +use std::f64; +use std::num::{FPNaN, FPInfinite}; +use std::io::{IoError, IoResult, MemWriter}; + +use ser::Serialize; +use ser; + +fn escape_bytes(wr: &mut W, bytes: &[u8]) -> 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, v: &str) -> IoResult<()> { + escape_bytes(wr, v.as_bytes()) +} + +fn escape_char(wr: &mut W, v: char) -> IoResult<()> { + let mut buf = [0, .. 4]; + v.encode_utf8(buf); + escape_bytes(wr, buf) +} + +fn fmt_f32_or_null(wr: &mut W, v: f32) -> IoResult<()> { + match v.classify() { + FPNaN | FPInfinite => wr.write_str("null"), + _ => wr.write_str(f32::to_str_digits(v, 6).as_slice()), + } +} + +fn fmt_f64_or_null(wr: &mut W, v: f64) -> IoResult<()> { + match v.classify() { + FPNaN | FPInfinite => wr.write_str("null"), + _ => wr.write_str(f64::to_str_digits(v, 6).as_slice()), + } +} + +fn spaces(wr: &mut W, mut n: uint) -> IoResult<()> { + const LEN: uint = 16; + const BUF: [u8, ..LEN] = [b' ', ..LEN]; + + while n >= LEN { + try!(wr.write(BUF)); + n -= LEN; + } + + if n > 0 { + wr.write(BUF.slice_to(n)) + } else { + Ok(()) + } +} + +/* +#[deriving(Show)] +enum SerializerState { + ValueState, + TupleState, + StructState, + EnumState, +} +*/ + +/// A structure for implementing serialization to JSON. +pub struct Serializer { + wr: W, + first: bool, +} + +impl Serializer { + /// Creates a new JSON serializer whose output will be written to the writer + /// specified. + pub fn new(wr: W) -> Serializer { + Serializer { + wr: wr, + first: true, + } + } + + /// Unwrap the Writer from the Serializer. + pub fn unwrap(self) -> W { + self.wr + } +} + +impl ser::Serializer for Serializer { + #[inline] + fn serialize_null(&mut self) -> IoResult<()> { + self.wr.write_str("null") + } + + #[inline] + fn serialize_bool(&mut self, v: bool) -> IoResult<()> { + if v { + self.wr.write_str("true") + } else { + self.wr.write_str("false") + } + } + + #[inline] + fn serialize_int(&mut self, v: int) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_i8(&mut self, v: i8) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_i16(&mut self, v: i16) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_i32(&mut self, v: i32) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_i64(&mut self, v: i64) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_uint(&mut self, v: uint) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_u8(&mut self, v: u8) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_u16(&mut self, v: u16) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_u32(&mut self, v: u32) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_u64(&mut self, v: u64) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_f32(&mut self, v: f32) -> IoResult<()> { + fmt_f32_or_null(&mut self.wr, v) + } + + #[inline] + fn serialize_f64(&mut self, v: f64) -> IoResult<()> { + fmt_f64_or_null(&mut self.wr, v) + } + + #[inline] + fn serialize_char(&mut self, v: char) -> IoResult<()> { + escape_char(&mut self.wr, v) + } + + #[inline] + fn serialize_str(&mut self, v: &str) -> IoResult<()> { + escape_str(&mut self.wr, v) + } + + #[inline] + fn serialize_tuple_start(&mut self, _len: uint) -> IoResult<()> { + self.first = true; + self.wr.write_str("[") + } + + #[inline] + fn serialize_tuple_elt< + T: Serialize, IoError> + >(&mut self, value: &T) -> IoResult<()> { + if self.first { + self.first = false; + } else { + try!(self.wr.write_str(",")); + } + value.serialize(self) + } + + #[inline] + fn serialize_tuple_end(&mut self) -> IoResult<()> { + self.wr.write_str("]") + } + + #[inline] + fn serialize_struct_start(&mut self, _name: &str, _len: uint) -> IoResult<()> { + self.first = true; + self.wr.write_str("{") + } + + #[inline] + fn serialize_struct_elt< + T: Serialize, IoError> + >(&mut self, name: &str, value: &T) -> IoResult<()> { + if self.first { + self.first = false; + } else { + try!(self.wr.write_str(",")); + } + try!(name.serialize(self)); + try!(self.wr.write_str(":")); + value.serialize(self) + } + + #[inline] + fn serialize_struct_end(&mut self) -> IoResult<()> { + self.wr.write_str("}") + } + + #[inline] + fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: uint) -> IoResult<()> { + self.first = true; + try!(self.wr.write_str("{")); + try!(self.serialize_str(variant)); + self.wr.write_str(":[") + } + + #[inline] + fn serialize_enum_elt< + T: Serialize, IoError> + >(&mut self, value: &T) -> IoResult<()> { + if self.first { + self.first = false; + } else { + try!(self.wr.write_str(",")); + } + value.serialize(self) + } + + #[inline] + fn serialize_enum_end(&mut self) -> IoResult<()> { + self.wr.write_str("]}") + } + + #[inline] + fn serialize_option< + T: Serialize, IoError> + >(&mut self, v: &Option) -> IoResult<()> { + match *v { + Some(ref v) => { + v.serialize(self) + } + None => { + self.serialize_null() + } + } + } + + #[inline] + fn serialize_seq< + T: Serialize, IoError>, + Iter: Iterator + >(&mut self, mut iter: Iter) -> IoResult<()> { + try!(self.wr.write_str("[")); + let mut first = true; + for elt in iter { + if first { + first = false; + } else { + try!(self.wr.write_str(",")); + } + try!(elt.serialize(self)); + + } + self.wr.write_str("]") + } + + #[inline] + fn serialize_map< + K: Serialize, IoError>, + V: Serialize, IoError>, + Iter: Iterator<(K, V)> + >(&mut self, mut iter: Iter) -> IoResult<()> { + try!(self.wr.write_str("{")); + let mut first = true; + for (key, value) in iter { + if first { + first = false; + } else { + try!(self.wr.write_str(",")); + } + try!(key.serialize(self)); + try!(self.wr.write_str(":")); + try!(value.serialize(self)); + } + self.wr.write_str("}") + } +} + +/// Another serializer for JSON, but prints out human-readable JSON instead of +/// compact data +pub struct PrettySerializer { + wr: W, + indent: uint, + first: bool, +} + +impl PrettySerializer { + /// Creates a new serializer whose output will be written to the specified writer + pub fn new(wr: W) -> PrettySerializer { + PrettySerializer { + wr: wr, + indent: 0, + first: true, + } + } + + /// Unwrap the Writer from the Serializer. + pub fn unwrap(self) -> W { + self.wr + } + + #[inline] + fn serialize_sep(&mut self) -> IoResult<()> { + if self.first { + self.first = false; + self.indent += 2; + try!(self.wr.write_str("\n")); + } else { + try!(self.wr.write_str(",\n")); + } + + spaces(&mut self.wr, self.indent) + } + + #[inline] + fn serialize_end(&mut self, s: &str) -> IoResult<()> { + if !self.first { + try!(self.wr.write_str("\n")); + self.indent -= 2; + try!(spaces(&mut self.wr, self.indent)); + } + + self.first = false; + + self.wr.write_str(s) + } +} + +impl ser::Serializer for PrettySerializer { + #[inline] + fn serialize_null(&mut self) -> IoResult<()> { + self.wr.write_str("null") + } + + #[inline] + fn serialize_bool(&mut self, v: bool) -> IoResult<()> { + if v { + self.wr.write_str("true") + } else { + self.wr.write_str("false") + } + } + + #[inline] + fn serialize_int(&mut self, v: int) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_i8(&mut self, v: i8) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_i16(&mut self, v: i16) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_i32(&mut self, v: i32) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_i64(&mut self, v: i64) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_uint(&mut self, v: uint) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_u8(&mut self, v: u8) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_u16(&mut self, v: u16) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_u32(&mut self, v: u32) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_u64(&mut self, v: u64) -> IoResult<()> { + write!(self.wr, "{}", v) + } + + #[inline] + fn serialize_f32(&mut self, v: f32) -> IoResult<()> { + fmt_f32_or_null(&mut self.wr, v) + } + + #[inline] + fn serialize_f64(&mut self, v: f64) -> IoResult<()> { + fmt_f64_or_null(&mut self.wr, v) + } + + #[inline] + fn serialize_char(&mut self, v: char) -> IoResult<()> { + escape_char(&mut self.wr, v) + } + + #[inline] + fn serialize_str(&mut self, v: &str) -> IoResult<()> { + escape_str(&mut self.wr, v) + } + + #[inline] + fn serialize_tuple_start(&mut self, _len: uint) -> IoResult<()> { + self.first = true; + self.wr.write_str("[") + } + + #[inline] + fn serialize_tuple_elt< + T: Serialize, IoError> + >(&mut self, value: &T) -> IoResult<()> { + try!(self.serialize_sep()); + value.serialize(self) + } + + #[inline] + fn serialize_tuple_end(&mut self) -> IoResult<()> { + self.serialize_end("]") + } + + #[inline] + fn serialize_struct_start(&mut self, _name: &str, _len: uint) -> IoResult<()> { + self.first = true; + self.wr.write_str("{") + } + + #[inline] + fn serialize_struct_elt< + T: Serialize, IoError> + >(&mut self, name: &str, value: &T) -> IoResult<()> { + try!(self.serialize_sep()); + try!(self.serialize_str(name)); + try!(self.wr.write_str(": ")); + value.serialize(self) + } + + #[inline] + fn serialize_struct_end(&mut self) -> IoResult<()> { + self.serialize_end("}") + } + + #[inline] + fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: uint) -> IoResult<()> { + self.first = true; + try!(self.wr.write_str("{")); + try!(self.serialize_sep()); + try!(self.serialize_str(variant)); + self.first = true; + self.wr.write_str(": [") + } + + #[inline] + fn serialize_enum_elt< + T: Serialize, IoError> + >(&mut self, value: &T) -> IoResult<()> { + try!(self.serialize_sep()); + value.serialize(self) + } + + #[inline] + fn serialize_enum_end(&mut self) -> IoResult<()> { + try!(self.serialize_tuple_end()); + self.serialize_struct_end() + } + + #[inline] + fn serialize_option< + T: Serialize, IoError> + >(&mut self, v: &Option) -> IoResult<()> { + match *v { + Some(ref v) => { + v.serialize(self) + } + None => { + self.serialize_null() + } + } + } + + #[inline] + fn serialize_seq< + T: Serialize, IoError>, + Iter: Iterator + >(&mut self, mut iter: Iter) -> IoResult<()> { + try!(self.wr.write_str("[")); + + self.first = true; + for elt in iter { + try!(self.serialize_sep()); + try!(elt.serialize(self)); + } + + self.serialize_end("]") + } + + #[inline] + fn serialize_map< + K: Serialize, IoError>, + V: Serialize, IoError>, + Iter: Iterator<(K, V)> + >(&mut self, mut iter: Iter) -> IoResult<()> { + try!(self.wr.write_str("{")); + + self.first = true; + for (key, value) in iter { + try!(self.serialize_sep()); + try!(key.serialize(self)); + try!(self.wr.write_str(": ")); + try!(value.serialize(self)); + } + + self.serialize_end("}") + } +} + +/// Encode the specified struct into a json `[u8]` writer. +#[inline] +pub fn to_writer< + W: Writer, + T: Serialize, IoError> +>(writer: W, value: &T) -> IoResult { + let mut serializer = Serializer::new(writer); + try!(value.serialize(&mut serializer)); + Ok(serializer.unwrap()) +} + +/// Encode the specified struct into a json `[u8]` buffer. +#[inline] +pub fn to_vec< + T: Serialize, IoError> +>(value: &T) -> Vec { + // We are writing to a Vec, which doesn't fail. So we can ignore + // the error. + let writer = MemWriter::with_capacity(128); + to_writer(writer, value).unwrap().unwrap() +} + +/// Encode the specified struct into a json `String` buffer. +#[inline] +pub fn to_string< + T: Serialize, IoError> +>(value: &T) -> Result> { + let buf = to_vec(value); + String::from_utf8(buf) +} + +/// Encode the specified struct into a json `[u8]` writer. +#[inline] +pub fn to_pretty_writer< + W: Writer, + T: Serialize, IoError> +>(writer: W, value: &T) -> IoResult { + let mut serializer = PrettySerializer::new(writer); + try!(value.serialize(&mut serializer)); + Ok(serializer.unwrap()) +} + +/// Encode the specified struct into a json `[u8]` buffer. +pub fn to_pretty_vec< + T: Serialize, IoError> +>(value: &T) -> Vec { + // We are writing to a Vec, which doesn't fail. So we can ignore + // the error. + let writer = MemWriter::with_capacity(128); + to_pretty_writer(writer, value).unwrap().unwrap() +} + +/// Encode the specified struct into a json `String` buffer. +pub fn to_pretty_string< + T: Serialize, IoError> +>(value: &T) -> Result> { + let buf = to_pretty_vec(value); + String::from_utf8(buf) +} diff --git a/src/json/value.rs b/src/json/value.rs index d27427f6..c894e598 100644 --- a/src/json/value.rs +++ b/src/json/value.rs @@ -12,7 +12,6 @@ use ser; use super::PrettySerializer; use super::Serializer; -use super::SerializeResult; use super::Error; use super::{ MissingFieldError, @@ -40,14 +39,14 @@ pub enum Value { impl Value { /// Serializes a json value into an io::writer. Uses a single line. - pub fn to_writer(&self, wr: W) -> SerializeResult { + pub fn to_writer(&self, wr: W) -> IoResult<()> { let mut serializer = Serializer::new(wr); self.serialize(&mut serializer) } /// Serializes a json value into an io::writer. /// Pretty-prints in a more readable format. - pub fn to_pretty_writer(&self, wr: W) -> SerializeResult { + pub fn to_pretty_writer(&self, wr: W) -> IoResult<()> { let mut serializer = PrettySerializer::new(wr); self.serialize(&mut serializer) }