diff --git a/serde_json/Cargo.toml b/serde_json/Cargo.toml deleted file mode 100644 index cc9665cf..00000000 --- a/serde_json/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "serde_json" -version = "0.5.1" -authors = ["Erick Tryzelaar "] -license = "MIT/Apache-2.0" -description = "A JSON serialization file format" -repository = "https://github.com/serde-rs/serde" -documentation = "https://serde-rs.github.io/serde/serde_json/serde_json/index.html" -readme = "../README.md" -keywords = ["json", "serde", "serialization"] - -[dependencies] -num = "*" -serde = { version = "*", path = "../serde" } diff --git a/serde_json/src/builder.rs b/serde_json/src/builder.rs deleted file mode 100644 index 2743b3d9..00000000 --- a/serde_json/src/builder.rs +++ /dev/null @@ -1,85 +0,0 @@ -// 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::BTreeMap; - -use serde::ser::{self, Serialize}; - -use value::{self, Value}; - -pub struct ArrayBuilder { - array: Vec, -} - -impl ArrayBuilder { - pub fn new() -> ArrayBuilder { - ArrayBuilder { array: Vec::new() } - } - - pub fn unwrap(self) -> Value { - Value::Array(self.array) - } - - pub fn push(mut self, v: T) -> ArrayBuilder { - self.array.push(value::to_value(&v)); - self - } - - pub fn push_array(mut self, f: F) -> ArrayBuilder where - F: FnOnce(ArrayBuilder) -> ArrayBuilder - { - let builder = ArrayBuilder::new(); - self.array.push(f(builder).unwrap()); - self - } - - pub fn push_object(mut self, f: F) -> ArrayBuilder where - F: FnOnce(ObjectBuilder) -> ObjectBuilder - { - let builder = ObjectBuilder::new(); - self.array.push(f(builder).unwrap()); - self - } -} - -pub struct ObjectBuilder { - object: BTreeMap, -} - -impl ObjectBuilder { - pub fn new() -> ObjectBuilder { - ObjectBuilder { object: BTreeMap::new() } - } - - pub fn unwrap(self) -> Value { - Value::Object(self.object) - } - - pub fn insert(mut self, k: String, v: V) -> ObjectBuilder { - self.object.insert(k, value::to_value(&v)); - self - } - - pub fn insert_array(mut self, key: String, f: F) -> ObjectBuilder where - F: FnOnce(ArrayBuilder) -> ArrayBuilder - { - let builder = ArrayBuilder::new(); - self.object.insert(key, f(builder).unwrap()); - self - } - - pub fn insert_object(mut self, key: String, f: F) -> ObjectBuilder where - F: FnOnce(ObjectBuilder) -> ObjectBuilder - { - let builder = ObjectBuilder::new(); - self.object.insert(key, f(builder).unwrap()); - self - } -} diff --git a/serde_json/src/de.rs b/serde_json/src/de.rs deleted file mode 100644 index 6940f94f..00000000 --- a/serde_json/src/de.rs +++ /dev/null @@ -1,820 +0,0 @@ -use std::char; -use std::i32; -use std::io; -use std::str; - -use serde::de; -use serde::iter::LineColIterator; - -use super::error::{Error, ErrorCode, Result}; - -pub struct Deserializer>> { - rdr: LineColIterator, - ch: Option, - str_buf: Vec, -} - -macro_rules! try_or_invalid { - ($self_:expr, $e:expr) => { - match $e { - Some(v) => v, - None => { return Err($self_.error(ErrorCode::InvalidNumber)); } - } - } -} - -impl Deserializer - where Iter: Iterator>, -{ - /// Creates the JSON parser from an `std::iter::Iterator`. - #[inline] - pub fn new(rdr: Iter) -> Deserializer { - Deserializer { - rdr: LineColIterator::new(rdr), - ch: None, - str_buf: Vec::with_capacity(128), - } - } - - #[inline] - pub fn end(&mut self) -> Result<()> { - try!(self.parse_whitespace()); - if try!(self.eof()) { - Ok(()) - } else { - Err(self.error(ErrorCode::TrailingCharacters)) - } - } - - fn eof(&mut self) -> Result { - Ok(try!(self.peek()).is_none()) - } - - fn peek(&mut self) -> Result> { - match self.ch { - Some(ch) => Ok(Some(ch)), - None => { - match self.rdr.next() { - Some(Err(err)) => Err(Error::IoError(err)), - Some(Ok(ch)) => { - self.ch = Some(ch); - Ok(self.ch) - } - None => Ok(None), - } - } - } - } - - fn peek_or_null(&mut self) -> Result { - Ok(try!(self.peek()).unwrap_or(b'\x00')) - } - - fn eat_char(&mut self) { - self.ch = None; - } - - fn next_char(&mut self) -> Result> { - match self.ch.take() { - Some(ch) => Ok(Some(ch)), - None => { - match self.rdr.next() { - Some(Err(err)) => Err(Error::IoError(err)), - Some(Ok(ch)) => Ok(Some(ch)), - None => Ok(None), - } - } - } - } - - fn next_char_or_null(&mut self) -> Result { - Ok(try!(self.next_char()).unwrap_or(b'\x00')) - } - - fn error(&mut self, reason: ErrorCode) -> Error { - Error::SyntaxError(reason, self.rdr.line(), self.rdr.col()) - } - - fn parse_whitespace(&mut self) -> Result<()> { - loop { - match try!(self.peek_or_null()) { - b' ' | b'\n' | b'\t' | b'\r' => { - self.eat_char(); - } - _ => { return Ok(()); } - } - } - } - - fn parse_value(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - try!(self.parse_whitespace()); - - if try!(self.eof()) { - return Err(self.error(ErrorCode::EOFWhileParsingValue)); - } - - let value = match try!(self.peek_or_null()) { - b'n' => { - self.eat_char(); - try!(self.parse_ident(b"ull")); - visitor.visit_unit() - } - b't' => { - self.eat_char(); - try!(self.parse_ident(b"rue")); - visitor.visit_bool(true) - } - b'f' => { - self.eat_char(); - try!(self.parse_ident(b"alse")); - visitor.visit_bool(false) - } - b'-' => { - self.eat_char(); - self.parse_integer(false, visitor) - } - b'0' ... b'9' => { - self.parse_integer(true, visitor) - } - b'"' => { - self.eat_char(); - try!(self.parse_string()); - let s = str::from_utf8(&self.str_buf).unwrap(); - visitor.visit_str(s) - } - b'[' => { - self.eat_char(); - visitor.visit_seq(SeqVisitor::new(self)) - } - b'{' => { - self.eat_char(); - visitor.visit_map(MapVisitor::new(self)) - } - _ => { - Err(self.error(ErrorCode::ExpectedSomeValue)) - } - }; - - match value { - Ok(value) => Ok(value), - Err(Error::SyntaxError(code, _, _)) => Err(self.error(code)), - Err(err) => Err(err), - } - } - - fn parse_ident(&mut self, ident: &[u8]) -> Result<()> { - for c in ident { - if Some(*c) != try!(self.next_char()) { - return Err(self.error(ErrorCode::ExpectedSomeIdent)); - } - } - - Ok(()) - } - - fn parse_integer(&mut self, pos: bool, visitor: V) -> Result - where V: de::Visitor, - { - match try!(self.next_char_or_null()) { - b'0' => { - // There can be only one leading '0'. - match try!(self.peek_or_null()) { - b'0' ... b'9' => { - Err(self.error(ErrorCode::InvalidNumber)) - } - _ => { - self.parse_number(pos, 0, visitor) - } - } - }, - c @ b'1' ... b'9' => { - let mut res: u64 = (c as u64) - ('0' as u64); - - loop { - match try!(self.peek_or_null()) { - c @ b'0' ... b'9' => { - self.eat_char(); - - let digit = (c as u64) - ('0' as u64); - - // We need to be careful with overflow. If we can, try to keep the - // number as a `u64` until we grow too large. At that point, switch to - // parsing the value as a `f64`. - match res.checked_mul(10).and_then(|val| val.checked_add(digit)) { - Some(res_) => { res = res_; } - None => { - return self.parse_float( - pos, - (res as f64) * 10.0 + (digit as f64), - visitor); - } - } - } - _ => { - return self.parse_number(pos, res, visitor); - } - } - } - } - _ => { - Err(self.error(ErrorCode::InvalidNumber)) - } - } - } - - fn parse_float(&mut self, - pos: bool, - mut res: f64, - mut visitor: V) -> Result - where V: de::Visitor, - { - loop { - match try!(self.next_char_or_null()) { - c @ b'0' ... b'9' => { - let digit = (c as u64) - ('0' as u64); - - res *= 10.0; - res += digit as f64; - } - _ => { - match try!(self.peek_or_null()) { - b'.' => { - return self.parse_decimal(pos, res, visitor); - } - b'e' | b'E' => { - return self.parse_exponent(pos, res, visitor); - } - _ => { - if !pos { - res = -res; - } - - return visitor.visit_f64(res); - } - } - } - } - } - } - - fn parse_number(&mut self, - pos: bool, - res: u64, - mut visitor: V) -> Result - where V: de::Visitor, - { - match try!(self.peek_or_null()) { - b'.' => { - self.parse_decimal(pos, res as f64, visitor) - } - b'e' | b'E' => { - self.parse_exponent(pos, res as f64, visitor) - } - _ => { - if pos { - visitor.visit_u64(res) - } else { - // FIXME: `wrapping_neg` will be stable in Rust 1.2 - //let res_i64 = (res as i64).wrapping_neg(); - let res_i64 = (!res + 1) as i64; - - // Convert into a float if we underflow. - if res_i64 > 0 { - visitor.visit_f64(-(res as f64)) - } else { - visitor.visit_i64(res_i64) - } - } - } - } - } - - fn parse_decimal(&mut self, - pos: bool, - mut res: f64, - mut visitor: V) -> Result - where V: de::Visitor, - { - self.eat_char(); - - let mut dec = 0.1; - - // Make sure a digit follows the decimal place. - match try!(self.next_char_or_null()) { - c @ b'0' ... b'9' => { - res += (((c as u64) - (b'0' as u64)) as f64) * dec; - } - _ => { return Err(self.error(ErrorCode::InvalidNumber)); } - } - - loop { - match try!(self.peek_or_null()) { - c @ b'0' ... b'9' => { - self.eat_char(); - - dec /= 10.0; - res += (((c as u64) - (b'0' as u64)) as f64) * dec; - } - _ => { break; } - } - } - - match try!(self.peek_or_null()) { - b'e' | b'E' => { - self.parse_exponent(pos, res, visitor) - } - _ => { - if pos { - visitor.visit_f64(res) - } else { - visitor.visit_f64(-res) - } - } - } - - } - - fn parse_exponent(&mut self, - pos: bool, - mut res: f64, - mut visitor: V) -> Result - where V: de::Visitor, - { - self.eat_char(); - - let pos_exp = match try!(self.peek_or_null()) { - b'+' => { self.eat_char(); true } - b'-' => { self.eat_char(); false } - _ => { true } - }; - - // Make sure a digit follows the exponent place. - let mut exp = match try!(self.next_char_or_null()) { - c @ b'0' ... b'9' => { (c as u64) - (b'0' as u64) } - _ => { return Err(self.error(ErrorCode::InvalidNumber)); } - }; - - loop { - match try!(self.peek_or_null()) { - c @ b'0' ... b'9' => { - self.eat_char(); - - exp = try_or_invalid!(self, exp.checked_mul(10)); - exp = try_or_invalid!(self, exp.checked_add((c as u64) - (b'0' as u64))); - } - _ => { break; } - } - } - - let exp = if exp <= i32::MAX as u64 { - 10_f64.powi(exp as i32) - } else { - return Err(self.error(ErrorCode::InvalidNumber)); - }; - - if pos_exp { - res *= exp; - } else { - res /= exp; - } - - if pos { - visitor.visit_f64(res) - } else { - visitor.visit_f64(-res) - } - } - - fn decode_hex_escape(&mut self) -> Result { - let mut i = 0; - let mut n = 0u16; - while i < 4 && !try!(self.eof()) { - n = match try!(self.next_char_or_null()) { - c @ b'0' ... b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)), - b'a' | b'A' => n * 16_u16 + 10_u16, - b'b' | b'B' => n * 16_u16 + 11_u16, - b'c' | b'C' => n * 16_u16 + 12_u16, - b'd' | b'D' => n * 16_u16 + 13_u16, - b'e' | b'E' => n * 16_u16 + 14_u16, - b'f' | b'F' => n * 16_u16 + 15_u16, - _ => { return Err(self.error(ErrorCode::InvalidEscape)); } - }; - - i += 1; - } - - // Error out if we didn't parse 4 digits. - if i != 4 { - return Err(self.error(ErrorCode::InvalidEscape)); - } - - Ok(n) - } - - fn parse_string(&mut self) -> Result<()> { - self.str_buf.clear(); - - loop { - let ch = match try!(self.next_char()) { - Some(ch) => ch, - None => { return Err(self.error(ErrorCode::EOFWhileParsingString)); } - }; - - match ch { - b'"' => { - return Ok(()); - } - b'\\' => { - let ch = match try!(self.next_char()) { - Some(ch) => ch, - None => { return Err(self.error(ErrorCode::EOFWhileParsingString)); } - }; - - match ch { - b'"' => self.str_buf.push(b'"'), - b'\\' => self.str_buf.push(b'\\'), - b'/' => self.str_buf.push(b'/'), - b'b' => self.str_buf.push(b'\x08'), - b'f' => self.str_buf.push(b'\x0c'), - b'n' => self.str_buf.push(b'\n'), - b'r' => self.str_buf.push(b'\r'), - b't' => self.str_buf.push(b'\t'), - b'u' => { - let c = match try!(self.decode_hex_escape()) { - 0xDC00 ... 0xDFFF => { - return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape)); - } - - // Non-BMP characters are encoded as a sequence of - // two hex escapes, representing UTF-16 surrogates. - n1 @ 0xD800 ... 0xDBFF => { - match (try!(self.next_char()), try!(self.next_char())) { - (Some(b'\\'), Some(b'u')) => (), - _ => { - return Err(self.error(ErrorCode::UnexpectedEndOfHexEscape)); - } - } - - let n2 = try!(self.decode_hex_escape()); - - if n2 < 0xDC00 || n2 > 0xDFFF { - return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape)); - } - - let n = (((n1 - 0xD800) as u32) << 10 | - (n2 - 0xDC00) as u32) + 0x1_0000; - - match char::from_u32(n as u32) { - Some(c) => c, - None => { - return Err(self.error(ErrorCode::InvalidUnicodeCodePoint)); - } - } - } - - n => { - match char::from_u32(n as u32) { - Some(c) => c, - None => { - return Err(self.error(ErrorCode::InvalidUnicodeCodePoint)); - } - } - } - }; - - // FIXME: this allocation is required in order to be compatible with stable - // rust, which doesn't support encoding a `char` into a stack buffer. - let buf = c.to_string(); - self.str_buf.extend(buf.bytes()); - } - _ => { - return Err(self.error(ErrorCode::InvalidEscape)); - } - } - } - ch => { - self.str_buf.push(ch); - } - } - } - } - - fn parse_object_colon(&mut self) -> Result<()> { - try!(self.parse_whitespace()); - - match try!(self.next_char()) { - Some(b':') => Ok(()), - Some(_) => Err(self.error(ErrorCode::ExpectedColon)), - None => Err(self.error(ErrorCode::EOFWhileParsingObject)), - } - } -} - -impl de::Deserializer for Deserializer - where Iter: Iterator>, -{ - type Error = Error; - - #[inline] - fn visit(&mut self, visitor: V) -> Result - where V: de::Visitor, - { - self.parse_value(visitor) - } - - /// Parses a `null` as a None, and any other values as a `Some(...)`. - #[inline] - fn visit_option(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - try!(self.parse_whitespace()); - - match try!(self.peek_or_null()) { - b'n' => { - self.eat_char(); - try!(self.parse_ident(b"ull")); - visitor.visit_none() - } - _ => { - visitor.visit_some(self) - } - } - } - - /// Parses a newtype struct as the underlying value. - #[inline] - fn visit_newtype_struct(&mut self, - _name: &str, - mut visitor: V) -> Result - where V: de::Visitor, - { - visitor.visit_newtype_struct(self) - } - - /// Parses an enum as an object like `{"$KEY":$VALUE}`, where $VALUE is either a straight - /// value, a `[..]`, or a `{..}`. - #[inline] - fn visit_enum(&mut self, - _name: &str, - _variants: &'static [&'static str], - mut visitor: V) -> Result - where V: de::EnumVisitor, - { - try!(self.parse_whitespace()); - - match try!(self.next_char_or_null()) { - b'{' => { - try!(self.parse_whitespace()); - - let value = { - try!(visitor.visit(&mut *self)) - }; - - try!(self.parse_whitespace()); - - match try!(self.next_char_or_null()) { - b'}' => { - Ok(value) - } - _ => { - Err(self.error(ErrorCode::ExpectedSomeValue)) - } - } - } - _ => { - Err(self.error(ErrorCode::ExpectedSomeValue)) - } - } - } - - #[inline] - fn format() -> &'static str { - "json" - } -} - -struct SeqVisitor<'a, Iter: 'a + Iterator>> { - de: &'a mut Deserializer, - first: bool, -} - -impl<'a, Iter: Iterator>> SeqVisitor<'a, Iter> { - fn new(de: &'a mut Deserializer) -> Self { - SeqVisitor { - de: de, - first: true, - } - } -} - -impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter> - where Iter: Iterator>, -{ - type Error = Error; - - fn visit(&mut self) -> Result> - where T: de::Deserialize, - { - try!(self.de.parse_whitespace()); - - match try!(self.de.peek()) { - Some(b']') => { - return Ok(None); - } - Some(b',') if !self.first => { - self.de.eat_char(); - } - Some(_) => { - if self.first { - self.first = false; - } else { - return Err(self.de.error(ErrorCode::ExpectedListCommaOrEnd)); - } - } - None => { - return Err(self.de.error(ErrorCode::EOFWhileParsingList)); - } - } - - let value = try!(de::Deserialize::deserialize(self.de)); - Ok(Some(value)) - } - - fn end(&mut self) -> Result<()> { - try!(self.de.parse_whitespace()); - - match try!(self.de.next_char()) { - Some(b']') => { Ok(()) } - Some(_) => { - Err(self.de.error(ErrorCode::TrailingCharacters)) - } - None => { - Err(self.de.error(ErrorCode::EOFWhileParsingList)) - } - } - } -} - -struct MapVisitor<'a, Iter: 'a + Iterator>> { - de: &'a mut Deserializer, - first: bool, -} - -impl<'a, Iter: Iterator>> MapVisitor<'a, Iter> { - fn new(de: &'a mut Deserializer) -> Self { - MapVisitor { - de: de, - first: true, - } - } -} - -impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter> - where Iter: Iterator> -{ - type Error = Error; - - fn visit_key(&mut self) -> Result> - where K: de::Deserialize, - { - try!(self.de.parse_whitespace()); - - match try!(self.de.peek()) { - Some(b'}') => { - return Ok(None); - } - Some(b',') if !self.first => { - self.de.eat_char(); - try!(self.de.parse_whitespace()); - } - Some(_) => { - if self.first { - self.first = false; - } else { - return Err(self.de.error(ErrorCode::ExpectedObjectCommaOrEnd)); - } - } - None => { - return Err(self.de.error(ErrorCode::EOFWhileParsingObject)); - } - } - - match try!(self.de.peek()) { - Some(b'"') => { - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - Some(_) => { - Err(self.de.error(ErrorCode::KeyMustBeAString)) - } - None => { - Err(self.de.error(ErrorCode::EOFWhileParsingValue)) - } - } - } - - fn visit_value(&mut self) -> Result - where V: de::Deserialize, - { - try!(self.de.parse_object_colon()); - - Ok(try!(de::Deserialize::deserialize(self.de))) - } - - fn end(&mut self) -> Result<()> { - try!(self.de.parse_whitespace()); - - match try!(self.de.next_char()) { - Some(b'}') => { Ok(()) } - Some(_) => { - Err(self.de.error(ErrorCode::TrailingCharacters)) - } - None => { - Err(self.de.error(ErrorCode::EOFWhileParsingObject)) - } - } - } - - fn missing_field(&mut self, _field: &'static str) -> Result - where V: de::Deserialize, - { - let mut de = de::value::ValueDeserializer::into_deserializer(()); - Ok(try!(de::Deserialize::deserialize(&mut de))) - } -} - -impl de::VariantVisitor for Deserializer - where Iter: Iterator>, -{ - type Error = Error; - - fn visit_variant(&mut self) -> Result - where V: de::Deserialize - { - let val = try!(de::Deserialize::deserialize(self)); - try!(self.parse_object_colon()); - Ok(val) - } - - fn visit_unit(&mut self) -> Result<()> { - de::Deserialize::deserialize(self) - } - - fn visit_newtype(&mut self) -> Result - where T: de::Deserialize, - { - de::Deserialize::deserialize(self) - } - - fn visit_tuple(&mut self, - _len: usize, - visitor: V) -> Result - where V: de::Visitor, - { - de::Deserializer::visit(self, visitor) - } - - fn visit_struct(&mut self, - _fields: &'static [&'static str], - visitor: V) -> Result - where V: de::Visitor, - { - de::Deserializer::visit(self, visitor) - } -} - -/// Decodes a json value from a `std::io::Read`. -pub fn from_iter(iter: I) -> Result - where I: Iterator>, - T: de::Deserialize, -{ - let mut de = Deserializer::new(iter); - let value = try!(de::Deserialize::deserialize(&mut de)); - - // Make sure the whole stream has been consumed. - try!(de.end()); - Ok(value) -} - -/// Decodes a json value from a `std::io::Read`. -pub fn from_reader(rdr: R) -> Result - where R: io::Read, - T: de::Deserialize, -{ - from_iter(rdr.bytes()) -} - -/// Decodes a json value from a `&str`. -pub fn from_slice(v: &[u8]) -> Result - where T: de::Deserialize -{ - from_iter(v.iter().map(|byte| Ok(*byte))) -} - -/// Decodes a json value from a `&str`. -pub fn from_str(s: &str) -> Result - where T: de::Deserialize -{ - from_slice(s.as_bytes()) -} diff --git a/serde_json/src/error.rs b/serde_json/src/error.rs deleted file mode 100644 index 6c3a494c..00000000 --- a/serde_json/src/error.rs +++ /dev/null @@ -1,175 +0,0 @@ -use std::error; -use std::fmt; -use std::io; -use std::result; -use std::string::FromUtf8Error; - -use serde::de; - -/// The errors that can arise while parsing a JSON stream. -#[derive(Clone, PartialEq)] -pub enum ErrorCode { - EOFWhileParsingList, - EOFWhileParsingObject, - EOFWhileParsingString, - EOFWhileParsingValue, - ExpectedColon, - ExpectedConversion, - ExpectedEnumEnd, - ExpectedEnumEndToken, - ExpectedEnumMapStart, - ExpectedEnumToken, - ExpectedEnumVariantString, - ExpectedListCommaOrEnd, - ExpectedName, - ExpectedObjectCommaOrEnd, - ExpectedSomeIdent, - ExpectedSomeValue, - InvalidEscape, - InvalidNumber, - InvalidUnicodeCodePoint, - KeyMustBeAString, - LoneLeadingSurrogateInHexEscape, - UnknownField(String), - MissingField(&'static str), - NotFourDigit, - NotUtf8, - TrailingCharacters, - UnexpectedEndOfHexEscape, - UnknownVariant, - UnrecognizedHex, -} - -impl fmt::Debug for ErrorCode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use std::fmt::Debug; - - match *self { - ErrorCode::EOFWhileParsingList => "EOF While parsing list".fmt(f), - ErrorCode::EOFWhileParsingObject => "EOF While parsing object".fmt(f), - ErrorCode::EOFWhileParsingString => "EOF While parsing string".fmt(f), - ErrorCode::EOFWhileParsingValue => "EOF While parsing value".fmt(f), - ErrorCode::ExpectedColon => "expected `:`".fmt(f), - ErrorCode::ExpectedConversion => "expected conversion".fmt(f), - ErrorCode::ExpectedEnumEnd => "expected enum end".fmt(f), - ErrorCode::ExpectedEnumEndToken => "expected enum map end".fmt(f), - ErrorCode::ExpectedEnumMapStart => "expected enum map start".fmt(f), - ErrorCode::ExpectedEnumToken => "expected enum token".fmt(f), - ErrorCode::ExpectedEnumVariantString => "expected variant".fmt(f), - ErrorCode::ExpectedListCommaOrEnd => "expected `,` or `]`".fmt(f), - ErrorCode::ExpectedName => "expected name".fmt(f), - ErrorCode::ExpectedObjectCommaOrEnd => "expected `,` or `}`".fmt(f), - ErrorCode::ExpectedSomeIdent => "expected ident".fmt(f), - ErrorCode::ExpectedSomeValue => "expected value".fmt(f), - ErrorCode::InvalidEscape => "invalid escape".fmt(f), - ErrorCode::InvalidNumber => "invalid number".fmt(f), - ErrorCode::InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f), - ErrorCode::KeyMustBeAString => "key must be a string".fmt(f), - ErrorCode::LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape".fmt(f), - ErrorCode::UnknownField(ref field) => write!(f, "unknown field \"{}\"", field), - ErrorCode::MissingField(ref field) => write!(f, "missing field \"{}\"", field), - ErrorCode::NotFourDigit => "invalid \\u escape (not four digits)".fmt(f), - ErrorCode::NotUtf8 => "contents not utf-8".fmt(f), - ErrorCode::TrailingCharacters => "trailing characters".fmt(f), - ErrorCode::UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f), - ErrorCode::UnknownVariant => "unknown variant".fmt(f), - ErrorCode::UnrecognizedHex => "invalid \\u escape (unrecognized hex)".fmt(f), - } - } -} - -#[derive(Debug)] -pub enum Error { - /// msg, line, col - SyntaxError(ErrorCode, usize, usize), - IoError(io::Error), - MissingFieldError(&'static str), - FromUtf8Error(FromUtf8Error), -} - -impl error::Error for Error { - fn description(&self) -> &str { - match *self { - Error::SyntaxError(..) => "syntax error", - Error::IoError(ref error) => error::Error::description(error), - Error::MissingFieldError(_) => "missing field", - Error::FromUtf8Error(ref error) => error.description(), - } - } - - fn cause(&self) -> Option<&error::Error> { - match *self { - Error::IoError(ref error) => Some(error), - Error::FromUtf8Error(ref error) => Some(error), - _ => None, - } - } - -} - -impl fmt::Display for Error { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - Error::SyntaxError(ref code, line, col) => { - write!(fmt, "{:?} at line {} column {}", code, line, col) - } - Error::IoError(ref error) => fmt::Display::fmt(error, fmt), - Error::FromUtf8Error(ref error) => fmt::Display::fmt(error, fmt), - Error::MissingFieldError(ref field) => { - write!(fmt, "missing field {}", field) - } - } - } -} - -impl From for Error { - fn from(error: io::Error) -> Error { - Error::IoError(error) - } -} - -impl From for Error { - fn from(error: FromUtf8Error) -> Error { - Error::FromUtf8Error(error) - } -} - -impl From for Error { - fn from(error: de::value::Error) -> Error { - match error { - de::value::Error::SyntaxError => { - Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0) - } - de::value::Error::EndOfStreamError => { - de::Error::end_of_stream() - } - de::value::Error::UnknownFieldError(field) => { - Error::SyntaxError(ErrorCode::UnknownField(field), 0, 0) - } - de::value::Error::MissingFieldError(field) => { - de::Error::missing_field(field) - } - } - } -} - -impl de::Error for Error { - fn syntax(_: &str) -> Error { - Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0) - } - - fn end_of_stream() -> Error { - Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0) - } - - fn unknown_field(field: &str) -> Error { - Error::SyntaxError(ErrorCode::UnknownField(field.to_string()), 0, 0) - } - - fn missing_field(field: &'static str) -> Error { - Error::MissingFieldError(field) - } -} - -/// Helper alias for `Result` objects that return a JSON `Error`. -pub type Result = result::Result; diff --git a/serde_json/src/lib.rs b/serde_json/src/lib.rs deleted file mode 100644 index 11ab52f2..00000000 --- a/serde_json/src/lib.rs +++ /dev/null @@ -1,122 +0,0 @@ -//! JSON and serialization -//! -//! # What is JSON? -//! -//! JSON (JavaScript Object Notation) is a way to write data in JavaScript. Like XML, it allows to -//! encode structured data in a text format that can be easily read by humans. Its simple syntax -//! and native compatibility with JavaScript have made it a widely used format. -//! -//! Data types that can be encoded are JavaScript types (see the `serde_json:Value` enum for more -//! details): -//! -//! * `Boolean`: equivalent to rust's `bool` -//! * `I64`: equivalent to rust's `i64` -//! * `U64`: equivalent to rust's `u64` -//! * `F64`: equivalent to rust's `i64` -//! * `String`: equivalent to rust's `String` -//! * `Array`: equivalent to rust's `Vec`, but also allowing objects of different types in the -//! same array -//! * `Object`: equivalent to rust's `BTreeMap` -//! * `Null` -//! -//! An object is a series of string keys mapping to values, in `"key": value` format. Arrays are -//! enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). A simple JSON -//! document encoding a person, his/her age, address and phone numbers could look like -//! -//! ```ignore -//! { -//! "FirstName": "John", -//! "LastName": "Doe", -//! "Age": 43, -//! "Address": { -//! "Street": "Downing Street 10", -//! "City": "London", -//! "Country": "Great Britain" -//! }, -//! "PhoneNumbers": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] -//! } -//! ``` -//! -//! # Type-based Serialization and Deserialization -//! -//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and -//! from JSON via the serialization API. To be able to serialize a piece of data, it must implement -//! the `serde::Serialize` trait. To be able to deserialize a piece of data, it must implement the -//! `serde::Deserialize` trait. Serde provides provides an annotation to automatically generate -//! the code for these traits: `#[derive(Serialize, Deserialize)]`. -//! -//! The JSON API also provides an enum `serde_json::Value` and a method `to_value` to serialize -//! objects. A `serde_json::Value` value can be serialized as a string or buffer using the -//! functions described above. You can also use the `json::Serializer` object, which implements the -//! `Serializer` trait. -//! -//! # Examples of use -//! -//! ## Parsing a `str` to `Value` and reading the result -//! -//! ```rust -//! //#![feature(custom_derive, plugin)] -//! //#![plugin(serde_macros)] -//! -//! extern crate serde_json; -//! -//! use serde_json::Value; -//! -//! fn main() { -//! let data: Value = serde_json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap(); -//! println!("data: {:?}", data); -//! // data: {"bar":"baz","foo":13} -//! println!("object? {}", data.is_object()); -//! // object? true -//! -//! let obj = data.as_object().unwrap(); -//! let foo = obj.get("foo").unwrap(); -//! -//! println!("array? {:?}", foo.as_array()); -//! // array? None -//! println!("u64? {:?}", foo.as_u64()); -//! // u64? Some(13u64) -//! -//! for (key, value) in obj.iter() { -//! println!("{}: {}", key, match *value { -//! Value::U64(v) => format!("{} (u64)", v), -//! Value::String(ref v) => format!("{} (string)", v), -//! _ => format!("other") -//! }); -//! } -//! // bar: baz (string) -//! // foo: 13 (u64) -//! } -//! ``` - -extern crate num; -extern crate serde; - -pub use self::de::{ - Deserializer, - from_iter, - from_reader, - from_slice, - from_str, -}; -pub use self::error::{Error, ErrorCode, Result}; -pub use self::ser::{ - Serializer, - to_writer, - to_writer_pretty, - to_vec, - to_vec_pretty, - to_string, - to_string_pretty, - escape_str, -}; -pub use self::value::{Value, to_value, from_value}; - -pub mod builder; -pub mod de; -pub mod error; -pub mod ser; -pub mod value; diff --git a/serde_json/src/ser.rs b/serde_json/src/ser.rs deleted file mode 100644 index 094022f5..00000000 --- a/serde_json/src/ser.rs +++ /dev/null @@ -1,637 +0,0 @@ -use std::io; -use std::num::FpCategory; - -use serde::ser; -use super::error::{Error, ErrorCode, Result}; - -/// A structure for implementing serialization to JSON. -pub struct Serializer { - writer: W, - formatter: F, - - /// `first` is used to signify if we should print a comma when we are walking through a - /// sequence. - first: bool, -} - -impl Serializer - where W: io::Write, -{ - /// Creates a new JSON serializer. - #[inline] - pub fn new(writer: W) -> Self { - Serializer::with_formatter(writer, CompactFormatter) - } -} - -impl<'a, W> Serializer> - where W: io::Write, -{ - /// Creates a new JSON pretty print serializer. - #[inline] - pub fn pretty(writer: W) -> Self { - Serializer::with_formatter(writer, PrettyFormatter::new()) - } -} - -impl Serializer - where W: io::Write, - F: Formatter, -{ - /// Creates a new JSON visitor whose output will be written to the writer - /// specified. - #[inline] - pub fn with_formatter(writer: W, formatter: F) -> Self { - Serializer { - writer: writer, - formatter: formatter, - first: false, - } - } - - /// Unwrap the `Writer` from the `Serializer`. - #[inline] - pub fn into_inner(self) -> W { - self.writer - } -} - -impl ser::Serializer for Serializer - where W: io::Write, - F: Formatter, -{ - type Error = Error; - - #[inline] - fn visit_bool(&mut self, value: bool) -> Result<()> { - if value { - self.writer.write_all(b"true").map_err(From::from) - } else { - self.writer.write_all(b"false").map_err(From::from) - } - } - - #[inline] - fn visit_isize(&mut self, value: isize) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_i8(&mut self, value: i8) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_i16(&mut self, value: i16) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_i32(&mut self, value: i32) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_i64(&mut self, value: i64) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_usize(&mut self, value: usize) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_u8(&mut self, value: u8) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_u16(&mut self, value: u16) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_u32(&mut self, value: u32) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_u64(&mut self, value: u64) -> Result<()> { - write!(&mut self.writer, "{}", value).map_err(From::from) - } - - #[inline] - fn visit_f32(&mut self, value: f32) -> Result<()> { - fmt_f32_or_null(&mut self.writer, value).map_err(From::from) - } - - #[inline] - fn visit_f64(&mut self, value: f64) -> Result<()> { - fmt_f64_or_null(&mut self.writer, value).map_err(From::from) - } - - #[inline] - fn visit_char(&mut self, value: char) -> Result<()> { - escape_char(&mut self.writer, value).map_err(From::from) - } - - #[inline] - fn visit_str(&mut self, value: &str) -> Result<()> { - escape_str(&mut self.writer, value).map_err(From::from) - } - - #[inline] - fn visit_none(&mut self) -> Result<()> { - self.visit_unit() - } - - #[inline] - fn visit_some(&mut self, value: V) -> Result<()> - where V: ser::Serialize - { - value.serialize(self) - } - - #[inline] - fn visit_unit(&mut self) -> Result<()> { - self.writer.write_all(b"null").map_err(From::from) - } - - /// Override `visit_newtype_struct` to serialize newtypes without an object wrapper. - #[inline] - fn visit_newtype_struct(&mut self, - _name: &'static str, - value: T) -> Result<()> - where T: ser::Serialize, - { - value.serialize(self) - } - - #[inline] - fn visit_unit_variant(&mut self, - _name: &str, - _variant_index: usize, - variant: &str) -> Result<()> { - try!(self.formatter.open(&mut self.writer, b'{')); - try!(self.formatter.comma(&mut self.writer, true)); - try!(self.visit_str(variant)); - try!(self.formatter.colon(&mut self.writer)); - try!(self.writer.write_all(b"[]")); - self.formatter.close(&mut self.writer, b'}') - } - - #[inline] - fn visit_newtype_variant(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - value: T) -> Result<()> - where T: ser::Serialize, - { - try!(self.formatter.open(&mut self.writer, b'{')); - try!(self.formatter.comma(&mut self.writer, true)); - try!(self.visit_str(variant)); - try!(self.formatter.colon(&mut self.writer)); - try!(value.serialize(self)); - self.formatter.close(&mut self.writer, b'}') - } - - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> Result<()> - where V: ser::SeqVisitor, - { - match visitor.len() { - Some(len) if len == 0 => { - self.writer.write_all(b"[]").map_err(From::from) - } - _ => { - try!(self.formatter.open(&mut self.writer, b'[')); - - self.first = true; - - while let Some(()) = try!(visitor.visit(self)) { } - - self.formatter.close(&mut self.writer, b']').map_err(From::from) - } - } - - } - - #[inline] - fn visit_tuple_variant(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<()> - where V: ser::SeqVisitor, - { - try!(self.formatter.open(&mut self.writer, b'{')); - try!(self.formatter.comma(&mut self.writer, true)); - try!(self.visit_str(variant)); - try!(self.formatter.colon(&mut self.writer)); - try!(self.visit_seq(visitor)); - self.formatter.close(&mut self.writer, b'}') - } - - #[inline] - fn visit_seq_elt(&mut self, value: T) -> Result<()> - where T: ser::Serialize, - { - try!(self.formatter.comma(&mut self.writer, self.first)); - try!(value.serialize(self)); - - self.first = false; - - Ok(()) - } - - #[inline] - fn visit_map(&mut self, mut visitor: V) -> Result<()> - where V: ser::MapVisitor, - { - match visitor.len() { - Some(len) if len == 0 => { - self.writer.write_all(b"{}").map_err(From::from) - } - _ => { - try!(self.formatter.open(&mut self.writer, b'{')); - - self.first = true; - - while let Some(()) = try!(visitor.visit(self)) { } - - self.formatter.close(&mut self.writer, b'}') - } - } - } - - #[inline] - fn visit_struct_variant(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<()> - where V: ser::MapVisitor, - { - try!(self.formatter.open(&mut self.writer, b'{')); - try!(self.formatter.comma(&mut self.writer, true)); - try!(self.visit_str(variant)); - try!(self.formatter.colon(&mut self.writer)); - try!(self.visit_map(visitor)); - - self.formatter.close(&mut self.writer, b'}') - } - - #[inline] - fn visit_map_elt(&mut self, key: K, value: V) -> Result<()> - where K: ser::Serialize, - V: ser::Serialize, - { - try!(self.formatter.comma(&mut self.writer, self.first)); - - try!(key.serialize(&mut MapKeySerializer { ser: self })); - try!(self.formatter.colon(&mut self.writer)); - try!(value.serialize(self)); - - self.first = false; - - Ok(()) - } - - #[inline] - fn format() -> &'static str { - "json" - } -} - -struct MapKeySerializer<'a, W: 'a, F: 'a> { - ser: &'a mut Serializer, -} - -impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F> - where W: io::Write, - F: Formatter, -{ - type Error = Error; - - #[inline] - fn visit_str(&mut self, value: &str) -> Result<()> { - self.ser.visit_str(value) - } - - fn visit_bool(&mut self, _value: bool) -> Result<()> { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_i64(&mut self, _value: i64) -> Result<()> { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_u64(&mut self, _value: u64) -> Result<()> { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_f64(&mut self, _value: f64) -> Result<()> { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_unit(&mut self) -> Result<()> { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_none(&mut self) -> Result<()> { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_some(&mut self, _value: V) -> Result<()> - where V: ser::Serialize - { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_seq(&mut self, _visitor: V) -> Result<()> - where V: ser::SeqVisitor, - { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_seq_elt(&mut self, _value: T) -> Result<()> - where T: ser::Serialize, - { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_map(&mut self, _visitor: V) -> Result<()> - where V: ser::MapVisitor, - { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } - - fn visit_map_elt(&mut self, _key: K, _value: V) -> Result<()> - where K: ser::Serialize, - V: ser::Serialize, - { - Err(Error::SyntaxError(ErrorCode::KeyMustBeAString, 0, 0)) - } -} - -pub trait Formatter { - fn open(&mut self, writer: &mut W, ch: u8) -> Result<()> - where W: io::Write; - - fn comma(&mut self, writer: &mut W, first: bool) -> Result<()> - where W: io::Write; - - fn colon(&mut self, writer: &mut W) -> Result<()> - where W: io::Write; - - fn close(&mut self, writer: &mut W, ch: u8) -> Result<()> - where W: io::Write; -} - -pub struct CompactFormatter; - -impl Formatter for CompactFormatter { - fn open(&mut self, writer: &mut W, ch: u8) -> Result<()> - where W: io::Write, - { - writer.write_all(&[ch]).map_err(From::from) - } - - fn comma(&mut self, writer: &mut W, first: bool) -> Result<()> - where W: io::Write, - { - if first { - Ok(()) - } else { - writer.write_all(b",").map_err(From::from) - } - } - - fn colon(&mut self, writer: &mut W) -> Result<()> - where W: io::Write, - { - writer.write_all(b":").map_err(From::from) - } - - fn close(&mut self, writer: &mut W, ch: u8) -> Result<()> - where W: io::Write, - { - writer.write_all(&[ch]).map_err(From::from) - } -} - -pub struct PrettyFormatter<'a> { - current_indent: usize, - indent: &'a [u8], -} - -impl<'a> PrettyFormatter<'a> { - fn new() -> Self { - PrettyFormatter::with_indent(b" ") - } - - fn with_indent(indent: &'a [u8]) -> Self { - PrettyFormatter { - current_indent: 0, - indent: indent, - } - } -} - -impl<'a> Formatter for PrettyFormatter<'a> { - fn open(&mut self, writer: &mut W, ch: u8) -> Result<()> - where W: io::Write, - { - self.current_indent += 1; - writer.write_all(&[ch]).map_err(From::from) - } - - fn comma(&mut self, writer: &mut W, first: bool) -> Result<()> - where W: io::Write, - { - if first { - try!(writer.write_all(b"\n")); - } else { - try!(writer.write_all(b",\n")); - } - - indent(writer, self.current_indent, self.indent) - } - - fn colon(&mut self, writer: &mut W) -> Result<()> - where W: io::Write, - { - writer.write_all(b": ").map_err(From::from) - } - - fn close(&mut self, writer: &mut W, ch: u8) -> Result<()> - where W: io::Write, - { - self.current_indent -= 1; - try!(writer.write(b"\n")); - try!(indent(writer, self.current_indent, self.indent)); - - writer.write_all(&[ch]).map_err(From::from) - } -} - -#[inline] -pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> Result<()> - where W: io::Write -{ - try!(wr.write_all(b"\"")); - - let mut start = 0; - - for (i, byte) in bytes.iter().enumerate() { - let escaped = match *byte { - b'"' => b"\\\"", - b'\\' => b"\\\\", - b'\x08' => b"\\b", - b'\x0c' => b"\\f", - b'\n' => b"\\n", - b'\r' => b"\\r", - b'\t' => b"\\t", - _ => { continue; } - }; - - if start < i { - try!(wr.write_all(&bytes[start..i])); - } - - try!(wr.write_all(escaped)); - - start = i + 1; - } - - if start != bytes.len() { - try!(wr.write_all(&bytes[start..])); - } - - try!(wr.write_all(b"\"")); - Ok(()) -} - -#[inline] -pub fn escape_str(wr: &mut W, value: &str) -> Result<()> - where W: io::Write -{ - escape_bytes(wr, value.as_bytes()) -} - -#[inline] -fn escape_char(wr: &mut W, value: char) -> Result<()> - where W: io::Write -{ - // FIXME: this allocation is required in order to be compatible with stable - // rust, which doesn't support encoding a `char` into a stack buffer. - escape_bytes(wr, value.to_string().as_bytes()) -} - -fn fmt_f32_or_null(wr: &mut W, value: f32) -> Result<()> - where W: io::Write -{ - match value.classify() { - FpCategory::Nan | FpCategory::Infinite => { - try!(wr.write_all(b"null")) - } - _ => { - try!(write!(wr, "{:?}", value)) - } - } - - Ok(()) -} - -fn fmt_f64_or_null(wr: &mut W, value: f64) -> Result<()> - where W: io::Write -{ - match value.classify() { - FpCategory::Nan | FpCategory::Infinite => { - try!(wr.write_all(b"null")) - } - _ => { - try!(write!(wr, "{:?}", value)) - } - } - - Ok(()) -} - -/// Encode the specified struct into a json `[u8]` writer. -#[inline] -pub fn to_writer(writer: &mut W, value: &T) -> Result<()> - where W: io::Write, - T: ser::Serialize, -{ - let mut ser = Serializer::new(writer); - try!(value.serialize(&mut ser)); - Ok(()) -} - -/// Encode the specified struct into a json `[u8]` writer. -#[inline] -pub fn to_writer_pretty(writer: &mut W, value: &T) -> Result<()> - where W: io::Write, - T: ser::Serialize, -{ - let mut ser = Serializer::pretty(writer); - try!(value.serialize(&mut ser)); - Ok(()) -} - -/// Encode the specified struct into a json `[u8]` buffer. -#[inline] -pub fn to_vec(value: &T) -> Result> - where T: ser::Serialize, -{ - // We are writing to a Vec, which doesn't fail. So we can ignore - // the error. - let mut writer = Vec::with_capacity(128); - try!(to_writer(&mut writer, value)); - Ok(writer) -} - -/// Encode the specified struct into a json `[u8]` buffer. -#[inline] -pub fn to_vec_pretty(value: &T) -> Result> - where T: ser::Serialize, -{ - // We are writing to a Vec, which doesn't fail. So we can ignore - // the error. - let mut writer = Vec::with_capacity(128); - try!(to_writer_pretty(&mut writer, value)); - Ok(writer) -} - -/// Encode the specified struct into a json `String` buffer. -#[inline] -pub fn to_string(value: &T) -> Result - where T: ser::Serialize -{ - let vec = try!(to_vec(value)); - let string = try!(String::from_utf8(vec)); - Ok(string) -} - -/// Encode the specified struct into a json `String` buffer. -#[inline] -pub fn to_string_pretty(value: &T) -> Result - where T: ser::Serialize -{ - let vec = try!(to_vec_pretty(value)); - let string = try!(String::from_utf8(vec)); - Ok(string) -} - -fn indent(wr: &mut W, n: usize, s: &[u8]) -> Result<()> - where W: io::Write, -{ - for _ in 0 .. n { - try!(wr.write_all(s)); - } - - Ok(()) -} diff --git a/serde_json/src/value.rs b/serde_json/src/value.rs deleted file mode 100644 index 6ef293ad..00000000 --- a/serde_json/src/value.rs +++ /dev/null @@ -1,951 +0,0 @@ -use std::collections::{BTreeMap, btree_map}; -use std::fmt; -use std::io; -use std::str; -use std::vec; - -use num::NumCast; - -use serde::de; -use serde::ser; - -use error::Error; - -#[derive(Clone, PartialEq)] -pub enum Value { - Null, - Bool(bool), - I64(i64), - U64(u64), - F64(f64), - String(String), - Array(Vec), - Object(BTreeMap), -} - -impl Value { - /// If the `Value` is an Object, returns the value associated with the provided key. - /// Otherwise, returns None. - pub fn find<'a>(&'a self, key: &str) -> Option<&'a Value>{ - match self { - &Value::Object(ref map) => map.get(key), - _ => None - } - } - - /// Attempts to get a nested Value Object for each key in `keys`. - /// If any key is found not to exist, find_path will return None. - /// Otherwise, it will return the `Value` associated with the final key. - pub fn find_path<'a>(&'a self, keys: &[&str]) -> Option<&'a Value>{ - let mut target = self; - for key in keys { - match target.find(key) { - Some(t) => { target = t; }, - None => return None - } - } - Some(target) - } - - /// Looks up a value by path. - /// - /// This is a convenience method that splits the path by `'.'` - /// and then feeds the sequence of keys into the `find_path` - /// method. - /// - /// ``` ignore - /// let obj: Value = json::from_str(r#"{"x": {"a": 1}}"#).unwrap(); - /// - /// assert!(obj.lookup("x.a").unwrap() == &Value::U64(1)); - /// ``` - pub fn lookup<'a>(&'a self, path: &str) -> Option<&'a Value> { - let mut target = self; - for key in path.split('.') { - match target.find(key) { - Some(t) => { target = t; }, - None => return None - } - } - Some(target) - } - - /// If the `Value` is an Object, performs a depth-first search until - /// a value associated with the provided key is found. If no value is found - /// or the `Value` is not an Object, returns None. - pub fn search<'a>(&'a self, key: &str) -> Option<&'a Value> { - match self { - &Value::Object(ref map) => { - match map.get(key) { - Some(json_value) => Some(json_value), - None => { - for (_, v) in map.iter() { - match v.search(key) { - x if x.is_some() => return x, - _ => () - } - } - None - } - } - }, - _ => None - } - } - - /// Returns true if the `Value` is an Object. Returns false otherwise. - pub fn is_object<'a>(&'a self) -> bool { - self.as_object().is_some() - } - - /// If the `Value` is an Object, returns the associated BTreeMap. - /// Returns None otherwise. - pub fn as_object<'a>(&'a self) -> Option<&'a BTreeMap> { - match self { - &Value::Object(ref map) => Some(map), - _ => None - } - } - - /// If the `Value` is an Object, returns the associated mutable BTreeMap. - /// Returns None otherwise. - pub fn as_object_mut<'a>(&'a mut self) -> Option<&'a mut BTreeMap> { - match self { - &mut Value::Object(ref mut map) => Some(map), - _ => None - } - } - - /// Returns true if the `Value` is an Array. Returns false otherwise. - pub fn is_array<'a>(&'a self) -> bool { - self.as_array().is_some() - } - - /// If the `Value` is an Array, returns the associated vector. - /// Returns None otherwise. - pub fn as_array<'a>(&'a self) -> Option<&'a Vec> { - match self { - &Value::Array(ref array) => Some(&*array), - _ => None - } - } - - /// If the `Value` is an Array, returns the associated mutable vector. - /// Returns None otherwise. - pub fn as_array_mut<'a>(&'a mut self) -> Option<&'a mut Vec> { - match self { - &mut Value::Array(ref mut list) => Some(list), - _ => None - } - } - - /// Returns true if the `Value` is a String. Returns false otherwise. - pub fn is_string<'a>(&'a self) -> bool { - self.as_string().is_some() - } - - /// If the `Value` is a String, returns the associated str. - /// Returns None otherwise. - pub fn as_string<'a>(&'a self) -> Option<&'a str> { - match *self { - Value::String(ref s) => Some(&s), - _ => None - } - } - - /// Returns true if the `Value` is a Number. Returns false otherwise. - pub fn is_number(&self) -> bool { - match *self { - Value::I64(_) | Value::U64(_) | Value::F64(_) => true, - _ => false, - } - } - - /// Returns true if the `Value` is a i64. Returns false otherwise. - pub fn is_i64(&self) -> bool { - match *self { - Value::I64(_) => true, - _ => false, - } - } - - /// Returns true if the `Value` is a u64. Returns false otherwise. - pub fn is_u64(&self) -> bool { - match *self { - Value::U64(_) => true, - _ => false, - } - } - - /// Returns true if the `Value` is a f64. Returns false otherwise. - pub fn is_f64(&self) -> bool { - match *self { - Value::F64(_) => true, - _ => false, - } - } - - /// If the `Value` is a number, return or cast it to a i64. - /// Returns None otherwise. - pub fn as_i64(&self) -> Option { - match *self { - Value::I64(n) => Some(n), - Value::U64(n) => NumCast::from(n), - _ => None - } - } - - /// If the `Value` is a number, return or cast it to a u64. - /// Returns None otherwise. - pub fn as_u64(&self) -> Option { - match *self { - Value::I64(n) => NumCast::from(n), - Value::U64(n) => Some(n), - _ => None - } - } - - /// If the `Value` is a number, return or cast it to a f64. - /// Returns None otherwise. - pub fn as_f64(&self) -> Option { - match *self { - Value::I64(n) => NumCast::from(n), - Value::U64(n) => NumCast::from(n), - Value::F64(n) => Some(n), - _ => None - } - } - - /// Returns true if the `Value` is a Boolean. Returns false otherwise. - pub fn is_boolean(&self) -> bool { - self.as_boolean().is_some() - } - - /// If the `Value` is a Boolean, returns the associated bool. - /// Returns None otherwise. - pub fn as_boolean(&self) -> Option { - match self { - &Value::Bool(b) => Some(b), - _ => None - } - } - - /// Returns true if the `Value` is a Null. Returns false otherwise. - pub fn is_null(&self) -> bool { - self.as_null().is_some() - } - - /// If the `Value` is a Null, returns (). - /// Returns None otherwise. - pub fn as_null(&self) -> Option<()> { - match self { - &Value::Null => Some(()), - _ => None - } - } -} - -impl ser::Serialize for Value { - #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: ser::Serializer, - { - match *self { - Value::Null => serializer.visit_unit(), - Value::Bool(v) => serializer.visit_bool(v), - Value::I64(v) => serializer.visit_i64(v), - Value::U64(v) => serializer.visit_u64(v), - Value::F64(v) => serializer.visit_f64(v), - Value::String(ref v) => serializer.visit_str(&v), - Value::Array(ref v) => v.serialize(serializer), - Value::Object(ref v) => v.serialize(serializer), - } - } -} - -impl de::Deserialize for Value { - #[inline] - fn deserialize(deserializer: &mut D) -> Result - where D: de::Deserializer, - { - struct ValueVisitor; - - impl de::Visitor for ValueVisitor { - type Value = Value; - - #[inline] - fn visit_bool(&mut self, value: bool) -> Result { - Ok(Value::Bool(value)) - } - - #[inline] - fn visit_i64(&mut self, value: i64) -> Result { - if value < 0 { - Ok(Value::I64(value)) - } else { - Ok(Value::U64(value as u64)) - } - } - - #[inline] - fn visit_u64(&mut self, value: u64) -> Result { - Ok(Value::U64(value)) - } - - #[inline] - fn visit_f64(&mut self, value: f64) -> Result { - Ok(Value::F64(value)) - } - - #[inline] - fn visit_str(&mut self, value: &str) -> Result - where E: de::Error, - { - self.visit_string(value.to_string()) - } - - #[inline] - fn visit_string(&mut self, value: String) -> Result { - Ok(Value::String(value)) - } - - #[inline] - fn visit_none(&mut self) -> Result { - Ok(Value::Null) - } - - #[inline] - fn visit_some(&mut self, deserializer: &mut D) -> Result - where D: de::Deserializer, - { - de::Deserialize::deserialize(deserializer) - } - - #[inline] - fn visit_unit(&mut self) -> Result { - Ok(Value::Null) - } - - #[inline] - fn visit_seq(&mut self, visitor: V) -> Result - where V: de::SeqVisitor, - { - let values = try!(de::impls::VecVisitor::new().visit_seq(visitor)); - Ok(Value::Array(values)) - } - - #[inline] - fn visit_map(&mut self, visitor: V) -> Result - where V: de::MapVisitor, - { - let values = try!(de::impls::BTreeMapVisitor::new().visit_map(visitor)); - Ok(Value::Object(values)) - } - } - - deserializer.visit(ValueVisitor) - } -} - -struct WriterFormatter<'a, 'b: 'a> { - inner: &'a mut fmt::Formatter<'b>, -} - -impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { - fn write(&mut self, buf: &[u8]) -> io::Result { - match self.inner.write_str(str::from_utf8(buf).unwrap()) { - Ok(_) => Ok(buf.len()), - Err(_) => Err(io::Error::last_os_error()), - } - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl fmt::Debug for Value { - /// Serializes a json value into a string - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut wr = WriterFormatter { inner: f }; - super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) - } -} - -#[derive(Debug)] -enum State { - Value(Value), - Array(Vec), - Object(BTreeMap), -} - -pub struct Serializer { - state: Vec, -} - -impl Serializer { - pub fn new() -> Serializer { - Serializer { - state: Vec::with_capacity(4), - } - } - - pub fn unwrap(mut self) -> Value { - match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - } - } -} - -impl ser::Serializer for Serializer { - type Error = (); - - #[inline] - fn visit_bool(&mut self, value: bool) -> Result<(), ()> { - self.state.push(State::Value(Value::Bool(value))); - Ok(()) - } - - #[inline] - fn visit_i64(&mut self, value: i64) -> Result<(), ()> { - if value < 0 { - self.state.push(State::Value(Value::I64(value))); - } else { - self.state.push(State::Value(Value::U64(value as u64))); - } - Ok(()) - } - - #[inline] - fn visit_u64(&mut self, value: u64) -> Result<(), ()> { - self.state.push(State::Value(Value::U64(value))); - Ok(()) - } - - #[inline] - fn visit_f64(&mut self, value: f64) -> Result<(), ()> { - self.state.push(State::Value(Value::F64(value as f64))); - Ok(()) - } - - #[inline] - fn visit_char(&mut self, value: char) -> Result<(), ()> { - self.state.push(State::Value(Value::String(value.to_string()))); - Ok(()) - } - - #[inline] - fn visit_str(&mut self, value: &str) -> Result<(), ()> { - self.state.push(State::Value(Value::String(value.to_string()))); - Ok(()) - } - - #[inline] - fn visit_none(&mut self) -> Result<(), ()> { - self.visit_unit() - } - - #[inline] - fn visit_some(&mut self, value: V) -> Result<(), ()> - where V: ser::Serialize, - { - value.serialize(self) - } - - #[inline] - fn visit_unit(&mut self) -> Result<(), ()> { - self.state.push(State::Value(Value::Null)); - Ok(()) - } - - #[inline] - fn visit_unit_variant(&mut self, - _name: &str, - _variant_index: usize, - variant: &str) -> Result<(), ()> { - let mut values = BTreeMap::new(); - values.insert(variant.to_string(), Value::Array(vec![])); - - self.state.push(State::Value(Value::Object(values))); - - Ok(()) - } - - #[inline] - fn visit_newtype_variant(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - value: T) -> Result<(), ()> - where T: ser::Serialize, - { - let mut values = BTreeMap::new(); - values.insert(variant.to_string(), to_value(&value)); - - self.state.push(State::Value(Value::Object(values))); - - Ok(()) - } - - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> Result<(), ()> - where V: ser::SeqVisitor, - { - let len = visitor.len().unwrap_or(0); - let values = Vec::with_capacity(len); - - self.state.push(State::Array(values)); - - while let Some(()) = try!(visitor.visit(self)) { } - - let values = match self.state.pop().unwrap() { - State::Array(values) => values, - state => panic!("Expected array, found {:?}", state), - }; - - self.state.push(State::Value(Value::Array(values))); - - Ok(()) - } - - #[inline] - fn visit_tuple_variant(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<(), ()> - where V: ser::SeqVisitor, - { - try!(self.visit_seq(visitor)); - - let value = match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - }; - - let mut object = BTreeMap::new(); - - object.insert(variant.to_string(), value); - - self.state.push(State::Value(Value::Object(object))); - - Ok(()) - } - - #[inline] - fn visit_seq_elt(&mut self, value: T) -> Result<(), ()> - where T: ser::Serialize, - { - try!(value.serialize(self)); - - let value = match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - }; - - match *self.state.last_mut().unwrap() { - State::Array(ref mut values) => { values.push(value); } - ref state => panic!("expected array, found {:?}", state), - } - - Ok(()) - } - - #[inline] - fn visit_map(&mut self, mut visitor: V) -> Result<(), ()> - where V: ser::MapVisitor, - { - let values = BTreeMap::new(); - - self.state.push(State::Object(values)); - - while let Some(()) = try!(visitor.visit(self)) { } - - let values = match self.state.pop().unwrap() { - State::Object(values) => values, - state => panic!("expected object, found {:?}", state), - }; - - self.state.push(State::Value(Value::Object(values))); - - Ok(()) - } - - #[inline] - fn visit_struct_variant(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<(), ()> - where V: ser::MapVisitor, - { - try!(self.visit_map(visitor)); - - let value = match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - }; - - let mut object = BTreeMap::new(); - - object.insert(variant.to_string(), value); - - self.state.push(State::Value(Value::Object(object))); - - Ok(()) - } - - #[inline] - fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), ()> - where K: ser::Serialize, - V: ser::Serialize, - { - try!(key.serialize(self)); - - let key = match self.state.pop().unwrap() { - State::Value(Value::String(value)) => value, - state => panic!("expected key, found {:?}", state), - }; - - try!(value.serialize(self)); - - let value = match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - }; - - match *self.state.last_mut().unwrap() { - State::Object(ref mut values) => { values.insert(key, value); } - ref state => panic!("expected object, found {:?}", state), - } - - Ok(()) - } - - #[inline] - fn format() -> &'static str { - "json" - } -} - -pub struct Deserializer { - value: Option, -} - -impl Deserializer { - /// Creates a new deserializer instance for deserializing the specified JSON value. - pub fn new(value: Value) -> Deserializer { - Deserializer { - value: Some(value), - } - } -} - -impl de::Deserializer for Deserializer { - type Error = Error; - - #[inline] - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - let value = match self.value.take() { - Some(value) => value, - None => { return Err(de::Error::end_of_stream()); } - }; - - match value { - Value::Null => visitor.visit_unit(), - Value::Bool(v) => visitor.visit_bool(v), - Value::I64(v) => visitor.visit_i64(v), - Value::U64(v) => visitor.visit_u64(v), - Value::F64(v) => visitor.visit_f64(v), - Value::String(v) => visitor.visit_string(v), - Value::Array(v) => { - let len = v.len(); - visitor.visit_seq(SeqDeserializer { - de: self, - iter: v.into_iter(), - len: len, - }) - } - Value::Object(v) => { - let len = v.len(); - visitor.visit_map(MapDeserializer { - de: self, - iter: v.into_iter(), - value: None, - len: len, - }) - } - } - } - - #[inline] - fn visit_option(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - match self.value { - Some(Value::Null) => visitor.visit_none(), - Some(_) => visitor.visit_some(self), - None => Err(de::Error::end_of_stream()), - } - } - - #[inline] - fn visit_enum(&mut self, - _name: &str, - _variants: &'static [&'static str], - mut visitor: V) -> Result - where V: de::EnumVisitor, - { - let value = match self.value.take() { - Some(Value::Object(value)) => value, - Some(_) => { return Err(de::Error::syntax("expected an enum")); } - None => { return Err(de::Error::end_of_stream()); } - }; - - let mut iter = value.into_iter(); - - let (variant, value) = match iter.next() { - Some(v) => v, - None => return Err(de::Error::syntax("expected a variant name")), - }; - - // enums are encoded in json as maps with a single key:value pair - match iter.next() { - Some(_) => Err(de::Error::syntax("expected map")), - None => visitor.visit(VariantDeserializer { - de: self, - val: Some(value), - variant: Some(Value::String(variant)), - }), - } - } - - #[inline] - fn visit_newtype_struct(&mut self, - _name: &'static str, - mut visitor: V) -> Result - where V: de::Visitor, - { - visitor.visit_newtype_struct(self) - } - - #[inline] - fn format() -> &'static str { - "json" - } -} - -struct VariantDeserializer<'a> { - de: &'a mut Deserializer, - val: Option, - variant: Option, -} - -impl<'a> de::VariantVisitor for VariantDeserializer<'a> { - type Error = Error; - - fn visit_variant(&mut self) -> Result - where V: de::Deserialize, - { - de::Deserialize::deserialize(&mut Deserializer::new(self.variant.take().unwrap())) - } - - fn visit_unit(&mut self) -> Result<(), Error> { - de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap())) - } - - fn visit_newtype(&mut self) -> Result - where T: de::Deserialize, - { - de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap())) - } - - fn visit_tuple(&mut self, - _len: usize, - visitor: V) -> Result - where V: de::Visitor, - { - if let Value::Array(fields) = self.val.take().unwrap() { - de::Deserializer::visit( - &mut SeqDeserializer { - de: self.de, - len: fields.len(), - iter: fields.into_iter(), - }, - visitor, - ) - } else { - Err(de::Error::syntax("expected a tuple")) - } - } - - fn visit_struct(&mut self, - _fields: &'static[&'static str], - visitor: V) -> Result - where V: de::Visitor, - { - if let Value::Object(fields) = self.val.take().unwrap() { - de::Deserializer::visit( - &mut MapDeserializer { - de: self.de, - len: fields.len(), - iter: fields.into_iter(), - value: None, - }, - visitor, - ) - } else { - Err(de::Error::syntax("expected a struct")) - } - } -} - -struct SeqDeserializer<'a> { - de: &'a mut Deserializer, - iter: vec::IntoIter, - len: usize, -} - -impl<'a> de::Deserializer for SeqDeserializer<'a> { - type Error = Error; - - #[inline] - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - if self.len == 0 { - visitor.visit_unit() - } else { - visitor.visit_seq(self) - } - } -} - -impl<'a> de::SeqVisitor for SeqDeserializer<'a> { - type Error = Error; - - fn visit(&mut self) -> Result, Error> - where T: de::Deserialize - { - match self.iter.next() { - Some(value) => { - self.len -= 1; - self.de.value = Some(value); - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - None => Ok(None), - } - } - - fn end(&mut self) -> Result<(), Error> { - if self.len == 0 { - Ok(()) - } else { - Err(de::Error::length_mismatch(self.len)) - } - } - - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -struct MapDeserializer<'a> { - de: &'a mut Deserializer, - iter: btree_map::IntoIter, - value: Option, - len: usize, -} - -impl<'a> de::MapVisitor for MapDeserializer<'a> { - type Error = Error; - - fn visit_key(&mut self) -> Result, Error> - where T: de::Deserialize - { - match self.iter.next() { - Some((key, value)) => { - self.len -= 1; - self.value = Some(value); - self.de.value = Some(Value::String(key)); - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - None => Ok(None), - } - } - - fn visit_value(&mut self) -> Result - where T: de::Deserialize - { - let value = self.value.take().unwrap(); - self.de.value = Some(value); - Ok(try!(de::Deserialize::deserialize(self.de))) - } - - fn end(&mut self) -> Result<(), Error> { - if self.len == 0 { - Ok(()) - } else { - Err(de::Error::length_mismatch(self.len)) - } - } - - fn missing_field(&mut self, _field: &'static str) -> Result - where V: de::Deserialize, - { - // See if the type can deserialize from a unit. - struct UnitDeserializer; - - impl de::Deserializer for UnitDeserializer { - type Error = Error; - - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - visitor.visit_unit() - } - - fn visit_option(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - visitor.visit_none() - } - } - - Ok(try!(de::Deserialize::deserialize(&mut UnitDeserializer))) - } - - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -impl<'a> de::Deserializer for MapDeserializer<'a> { - type Error = Error; - - #[inline] - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - visitor.visit_map(self) - } -} - -/// Shortcut function to encode a `T` into a JSON `Value` -pub fn to_value(value: &T) -> Value - where T: ser::Serialize -{ - let mut ser = Serializer::new(); - value.serialize(&mut ser).ok().unwrap(); - ser.unwrap() -} - -/// Shortcut function to decode a JSON `Value` into a `T` -pub fn from_value(value: Value) -> Result - where T: de::Deserialize -{ - let mut de = Deserializer::new(value); - de::Deserialize::deserialize(&mut de) -} diff --git a/serde_macros/Cargo.toml b/serde_macros/Cargo.toml index d254925a..3b4413bd 100644 --- a/serde_macros/Cargo.toml +++ b/serde_macros/Cargo.toml @@ -19,4 +19,3 @@ serde_codegen = { version = "*", path = "../serde_codegen", default-features = f num = "*" rustc-serialize = "*" serde = { version = "*", path = "../serde", features = ["nightly"] } -serde_json = { version = "*", path = "../serde_json" } diff --git a/serde_macros/benches/bench.rs b/serde_macros/benches/bench.rs index 514edc48..519c189f 100644 --- a/serde_macros/benches/bench.rs +++ b/serde_macros/benches/bench.rs @@ -4,7 +4,6 @@ extern crate num; extern crate rustc_serialize; extern crate serde; -extern crate serde_json; extern crate test; include!("../../serde_tests/benches/bench.rs.in"); diff --git a/serde_macros/examples/json.rs b/serde_macros/examples/json.rs deleted file mode 100644 index 50f5d199..00000000 --- a/serde_macros/examples/json.rs +++ /dev/null @@ -1,66 +0,0 @@ -#![feature(custom_derive, plugin)] -#![plugin(serde_macros)] - -extern crate serde; -extern crate serde_json; - -use std::collections::BTreeMap; - -// Creating serializable types with serde is quite simple with `serde_macros`. It implements a -// syntax extension that automatically generates the necessary serde trait implementations. -#[derive(Debug, Serialize, Deserialize)] -struct Point { - x: i32, - y: i32, -} - -fn main() { - let point = Point { x: 5, y: 6 }; - - // Serializing to JSON is pretty simple by using the `to_string` method: - let serialized_point = serde_json::to_string(&point).unwrap(); - - println!("{}", serialized_point); - // prints: - // - // {"x":5,"y":6} - - // There is also support for pretty printing using `to_string_pretty`: - let serialized_point = serde_json::to_string_pretty(&point).unwrap(); - - println!("{}", serialized_point); - // prints: - // - // { - // "x":5, - // "y":6 - // } - - // Values can also be deserialized with the same style using `from_str`: - let deserialized_point: Point = serde_json::from_str(&serialized_point).unwrap(); - - println!("{:?}", deserialized_point); - // prints: - // - // Point { x: 5, y: 6 } - - // `Point`s aren't the only type that can be serialized to. Because `Point` members have the - // same type, they can be also serialized into a map. Also, - let deserialized_map: BTreeMap = - serde_json::from_str(&serialized_point).unwrap(); - - println!("{:?}", deserialized_map); - // prints: - // - // {"x": 5, "y": 6} - - // If you need to accept arbitrary data, you can also deserialize into `serde_json::Value`, - // which can represent all JSON values. - let deserialized_value: serde_json::Value = - serde_json::from_str(&serialized_point).unwrap(); - - println!("{:?}", deserialized_value); - // prints: - // - // {"x":5,"y":6} -} diff --git a/serde_tests/benches/bench.rs b/serde_tests/benches/bench.rs index 7cc2fc32..181c4c61 100644 --- a/serde_tests/benches/bench.rs +++ b/serde_tests/benches/bench.rs @@ -3,7 +3,6 @@ extern crate num; extern crate rustc_serialize; extern crate serde; -extern crate serde_json; extern crate test; include!(concat!(env!("OUT_DIR"), "/bench.rs")); diff --git a/serde_tests/benches/bench.rs.in b/serde_tests/benches/bench.rs.in index 70caf460..d79b35f0 100644 --- a/serde_tests/benches/bench.rs.in +++ b/serde_tests/benches/bench.rs.in @@ -1,5 +1,4 @@ mod bench_enum; -mod bench_log; mod bench_map; mod bench_struct; mod bench_vec; diff --git a/serde_tests/benches/bench_log.rs b/serde_tests/benches/bench_log.rs deleted file mode 100644 index 1dddcf50..00000000 --- a/serde_tests/benches/bench_log.rs +++ /dev/null @@ -1,1606 +0,0 @@ -use std::io::{self, Read, Write}; -use num::FromPrimitive; -use test::{Bencher, black_box}; - -use rustc_serialize; - -use serde::de::{self, Deserialize, Deserializer}; -use serde::ser::{self, Serialize, Serializer}; -use serde_json::ser::escape_str; -use serde_json; -use std::str::FromStr; - -use rustc_serialize::Encodable; - -#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable, Serialize, Deserialize)] -struct Http { - protocol: HttpProtocol, - status: u32, - host_status: u32, - up_status: u32, - method: HttpMethod, - content_type: String, - user_agent: String, - referer: String, - request_uri: String, -} - -#[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, PartialEq)] -enum HttpProtocol { - HTTP_PROTOCOL_UNKNOWN, - HTTP10, - HTTP11, -} - -impl rustc_serialize::Encodable for HttpProtocol { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as usize).encode(s) - } -} - -impl rustc_serialize::Decodable for HttpProtocol { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_usize(try!(d.read_usize())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from usize")), - } - } -} - -impl FromStr for HttpProtocol { - type Err = (); - fn from_str(_s: &str) -> Result { unimplemented!() } -} - -impl FromPrimitive for HttpProtocol { - fn from_i64(i: i64) -> Option { - FromPrimitive::from_u64(i as u64) - } - - fn from_u64(n: u64) -> Option { - match n { - 0 => Some(HttpProtocol::HTTP_PROTOCOL_UNKNOWN), - 1 => Some(HttpProtocol::HTTP10), - 2 => Some(HttpProtocol::HTTP11), - _ => None, - } - } -} - -impl ser::Serialize for HttpProtocol { - #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: ser::Serializer, - { - serializer.visit_u8(*self as u8) - } -} - -impl de::Deserialize for HttpProtocol { - #[inline] - fn deserialize< - S: Deserializer, - >(state: &mut S) -> Result { - state.visit(de::impls::PrimitiveVisitor::new()) - } -} - -#[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, PartialEq)] -enum HttpMethod { - METHOD_UNKNOWN, - GET, - POST, - DELETE, - PUT, - HEAD, - PURGE, - OPTIONS, - PROPFIND, - MKCOL, - PATCH, -} - -impl FromStr for HttpMethod { - type Err = (); - fn from_str(_s: &str) -> Result { unimplemented!() } -} - -impl FromPrimitive for HttpMethod { - fn from_i64(i: i64) -> Option { - FromPrimitive::from_u64(i as u64) - } - - fn from_u64(n: u64) -> Option { - match n { - 0 => Some(HttpMethod::METHOD_UNKNOWN), - 1 => Some(HttpMethod::GET), - 2 => Some(HttpMethod::POST), - 3 => Some(HttpMethod::DELETE), - 4 => Some(HttpMethod::PUT), - 5 => Some(HttpMethod::HEAD), - 6 => Some(HttpMethod::PURGE), - 7 => Some(HttpMethod::OPTIONS), - 8 => Some(HttpMethod::PROPFIND), - 9 => Some(HttpMethod::MKCOL), - 10 => Some(HttpMethod::PATCH), - _ => None, - } - } -} - -impl rustc_serialize::Encodable for HttpMethod { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as usize).encode(s) - } -} - -impl rustc_serialize::Decodable for HttpMethod { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_usize(try!(d.read_usize())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from usize")), - } - } -} - -impl ser::Serialize for HttpMethod { - #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: ser::Serializer, - { - serializer.visit_u8(*self as u8) - } -} - -impl de::Deserialize for HttpMethod { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::impls::PrimitiveVisitor::new()) - } -} - -#[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, PartialEq)] -enum CacheStatus { - CACHESTATUS_UNKNOWN, - Miss, - Expired, - Hit, -} - -impl FromStr for CacheStatus { - type Err = (); - fn from_str(_s: &str) -> Result { unimplemented!() } -} - -impl FromPrimitive for CacheStatus { - fn from_i64(i: i64) -> Option { - FromPrimitive::from_u64(i as u64) - } - - fn from_u64(n: u64) -> Option { - match n { - 0 => Some(CacheStatus::CACHESTATUS_UNKNOWN), - 1 => Some(CacheStatus::Miss), - 2 => Some(CacheStatus::Expired), - 3 => Some(CacheStatus::Hit), - _ => None, - } - } -} - -impl rustc_serialize::Encodable for CacheStatus { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as u8).encode(s) - } -} - -impl rustc_serialize::Decodable for CacheStatus { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_u8(try!(d.read_u8())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from u8")), - } - } -} - -impl ser::Serialize for CacheStatus { - #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: ser::Serializer, - { - serializer.visit_u8(*self as u8) - } -} - -impl de::Deserialize for CacheStatus { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::impls::PrimitiveVisitor::new()) - } -} - -#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable, Serialize, Deserialize)] -struct Origin { - ip: String, - port: u32, - hostname: String, - protocol: OriginProtocol, -} - -#[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, PartialEq)] -enum OriginProtocol { - ORIGIN_PROTOCOL_UNKNOWN, - HTTP, - HTTPS, -} - -impl FromStr for OriginProtocol { - type Err = (); - fn from_str(_s: &str) -> Result { unimplemented!() } -} - -impl FromPrimitive for OriginProtocol { - fn from_i64(i: i64) -> Option { - FromPrimitive::from_u64(i as u64) - } - - fn from_u64(n: u64) -> Option { - match n { - 0 => Some(OriginProtocol::ORIGIN_PROTOCOL_UNKNOWN), - 1 => Some(OriginProtocol::HTTP), - 2 => Some(OriginProtocol::HTTPS), - _ => None, - } - } -} - -impl rustc_serialize::Encodable for OriginProtocol { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as u8).encode(s) - } -} - -impl rustc_serialize::Decodable for OriginProtocol { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_u8(try!(d.read_u8())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from u8")), - } - } -} - -impl ser::Serialize for OriginProtocol { - #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: ser::Serializer, - { - serializer.visit_u8(*self as u8) - } -} - -impl de::Deserialize for OriginProtocol { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::impls::PrimitiveVisitor::new()) - } -} - -#[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, PartialEq)] -enum ZonePlan { - ZONEPLAN_UNKNOWN, - FREE, - PRO, - BIZ, - ENT, -} - -impl FromStr for ZonePlan { - type Err = (); - fn from_str(_s: &str) -> Result { unimplemented!() } -} - -impl FromPrimitive for ZonePlan { - fn from_i64(i: i64) -> Option { - FromPrimitive::from_u64(i as u64) - } - - fn from_u64(n: u64) -> Option { - match n { - 0 => Some(ZonePlan::ZONEPLAN_UNKNOWN), - 1 => Some(ZonePlan::FREE), - 2 => Some(ZonePlan::PRO), - 3 => Some(ZonePlan::BIZ), - 4 => Some(ZonePlan::ENT), - _ => None, - } - } -} - -impl rustc_serialize::Encodable for ZonePlan { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as u8).encode(s) - } -} - -impl rustc_serialize::Decodable for ZonePlan { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_u8(try!(d.read_u8())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from u8")), - } - } -} - -impl ser::Serialize for ZonePlan { - #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: ser::Serializer, - { - serializer.visit_u8(*self as u8) - } -} - -impl de::Deserialize for ZonePlan { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::impls::PrimitiveVisitor::new()) - } -} - -#[derive(Copy, Clone, Debug, PartialEq)] -enum Country { - UNKNOWN, - A1, - A2, - O1, - AD, - AE, - AF, - AG, - AI, - AL, - AM, - AO, - AP, - AQ, - AR, - AS, - AT, - AU, - AW, - AX, - AZ, - BA, - BB, - BD, - BE, - BF, - BG, - BH, - BI, - BJ, - BL, - BM, - BN, - BO, - BQ, - BR, - BS, - BT, - BV, - BW, - BY, - BZ, - CA, - CC, - CD, - CF, - CG, - CH, - CI, - CK, - CL, - CM, - CN, - CO, - CR, - CU, - CV, - CW, - CX, - CY, - CZ, - DE, - DJ, - DK, - DM, - DO, - DZ, - EC, - EE, - EG, - EH, - ER, - ES, - ET, - EU, - FI, - FJ, - FK, - FM, - FO, - FR, - GA, - GB, - GD, - GE, - GF, - GG, - GH, - GI, - GL, - GM, - GN, - GP, - GQ, - GR, - GS, - GT, - GU, - GW, - GY, - HK, - HM, - HN, - HR, - HT, - HU, - ID, - IE, - IL, - IM, - IN, - IO, - IQ, - IR, - IS, - IT, - JE, - JM, - JO, - JP, - KE, - KG, - KH, - KI, - KM, - KN, - KP, - KR, - KW, - KY, - KZ, - LA, - LB, - LC, - LI, - LK, - LR, - LS, - LT, - LU, - LV, - LY, - MA, - MC, - MD, - ME, - MF, - MG, - MH, - MK, - ML, - MM, - MN, - MO, - MP, - MQ, - MR, - MS, - MT, - MU, - MV, - MW, - MX, - MY, - MZ, - NA, - NC, - NE, - NF, - NG, - NI, - NL, - NO, - NP, - NR, - NU, - NZ, - OM, - PA, - PE, - PF, - PG, - PH, - PK, - PL, - PM, - PN, - PR, - PS, - PT, - PW, - PY, - QA, - RE, - RO, - RS, - RU, - RW, - SA, - SB, - SC, - SD, - SE, - SG, - SH, - SI, - SJ, - SK, - SL, - SM, - SN, - SO, - SR, - SS, - ST, - SV, - SX, - SY, - SZ, - TC, - TD, - TF, - TG, - TH, - TJ, - TK, - TL, - TM, - TN, - TO, - TR, - TT, - TV, - TW, - TZ, - UA, - UG, - UM, - US, - UY, - UZ, - VA, - VC, - VE, - VG, - VI, - VN, - VU, - WF, - WS, - XX, - YE, - YT, - ZA, - ZM, - ZW, -} - -impl FromStr for Country { - type Err = (); - fn from_str(_s: &str) -> Result { unimplemented!() } -} - -impl FromPrimitive for Country { - fn from_i64(i: i64) -> Option { - FromPrimitive::from_u64(i as u64) - } - - fn from_u64(n: u64) -> Option { - match n { - 0 => Some(Country::UNKNOWN), - 1 => Some(Country::A1), - 2 => Some(Country::A2), - 3 => Some(Country::O1), - 4 => Some(Country::AD), - 5 => Some(Country::AE), - 6 => Some(Country::AF), - 7 => Some(Country::AG), - 8 => Some(Country::AI), - 9 => Some(Country::AL), - 10 => Some(Country::AM), - 11 => Some(Country::AO), - 12 => Some(Country::AP), - 13 => Some(Country::AQ), - 14 => Some(Country::AR), - 15 => Some(Country::AS), - 16 => Some(Country::AT), - 17 => Some(Country::AU), - 18 => Some(Country::AW), - 19 => Some(Country::AX), - 20 => Some(Country::AZ), - 21 => Some(Country::BA), - 22 => Some(Country::BB), - 23 => Some(Country::BD), - 24 => Some(Country::BE), - 25 => Some(Country::BF), - 26 => Some(Country::BG), - 27 => Some(Country::BH), - 28 => Some(Country::BI), - 29 => Some(Country::BJ), - 30 => Some(Country::BL), - 31 => Some(Country::BM), - 32 => Some(Country::BN), - 33 => Some(Country::BO), - 34 => Some(Country::BQ), - 35 => Some(Country::BR), - 36 => Some(Country::BS), - 37 => Some(Country::BT), - 38 => Some(Country::BV), - 39 => Some(Country::BW), - 40 => Some(Country::BY), - 41 => Some(Country::BZ), - 42 => Some(Country::CA), - 43 => Some(Country::CC), - 44 => Some(Country::CD), - 45 => Some(Country::CF), - 46 => Some(Country::CG), - 47 => Some(Country::CH), - 48 => Some(Country::CI), - 49 => Some(Country::CK), - 50 => Some(Country::CL), - 51 => Some(Country::CM), - 52 => Some(Country::CN), - 53 => Some(Country::CO), - 54 => Some(Country::CR), - 55 => Some(Country::CU), - 56 => Some(Country::CV), - 57 => Some(Country::CW), - 58 => Some(Country::CX), - 59 => Some(Country::CY), - 60 => Some(Country::CZ), - 61 => Some(Country::DE), - 62 => Some(Country::DJ), - 63 => Some(Country::DK), - 64 => Some(Country::DM), - 65 => Some(Country::DO), - 66 => Some(Country::DZ), - 67 => Some(Country::EC), - 68 => Some(Country::EE), - 69 => Some(Country::EG), - 70 => Some(Country::EH), - 71 => Some(Country::ER), - 72 => Some(Country::ES), - 73 => Some(Country::ET), - 74 => Some(Country::EU), - 75 => Some(Country::FI), - 76 => Some(Country::FJ), - 77 => Some(Country::FK), - 78 => Some(Country::FM), - 79 => Some(Country::FO), - 80 => Some(Country::FR), - 81 => Some(Country::GA), - 82 => Some(Country::GB), - 83 => Some(Country::GD), - 84 => Some(Country::GE), - 85 => Some(Country::GF), - 86 => Some(Country::GG), - 87 => Some(Country::GH), - 88 => Some(Country::GI), - 89 => Some(Country::GL), - 90 => Some(Country::GM), - 91 => Some(Country::GN), - 92 => Some(Country::GP), - 93 => Some(Country::GQ), - 94 => Some(Country::GR), - 95 => Some(Country::GS), - 96 => Some(Country::GT), - 97 => Some(Country::GU), - 98 => Some(Country::GW), - 99 => Some(Country::GY), - 100 => Some(Country::HK), - 101 => Some(Country::HM), - 102 => Some(Country::HN), - 103 => Some(Country::HR), - 104 => Some(Country::HT), - 105 => Some(Country::HU), - 106 => Some(Country::ID), - 107 => Some(Country::IE), - 108 => Some(Country::IL), - 109 => Some(Country::IM), - 110 => Some(Country::IN), - 111 => Some(Country::IO), - 112 => Some(Country::IQ), - 113 => Some(Country::IR), - 114 => Some(Country::IS), - 115 => Some(Country::IT), - 116 => Some(Country::JE), - 117 => Some(Country::JM), - 118 => Some(Country::JO), - 119 => Some(Country::JP), - 120 => Some(Country::KE), - 121 => Some(Country::KG), - 122 => Some(Country::KH), - 123 => Some(Country::KI), - 124 => Some(Country::KM), - 125 => Some(Country::KN), - 126 => Some(Country::KP), - 127 => Some(Country::KR), - 128 => Some(Country::KW), - 129 => Some(Country::KY), - 130 => Some(Country::KZ), - 131 => Some(Country::LA), - 132 => Some(Country::LB), - 133 => Some(Country::LC), - 134 => Some(Country::LI), - 135 => Some(Country::LK), - 136 => Some(Country::LR), - 137 => Some(Country::LS), - 138 => Some(Country::LT), - 139 => Some(Country::LU), - 140 => Some(Country::LV), - 141 => Some(Country::LY), - 142 => Some(Country::MA), - 143 => Some(Country::MC), - 144 => Some(Country::MD), - 145 => Some(Country::ME), - 146 => Some(Country::MF), - 147 => Some(Country::MG), - 148 => Some(Country::MH), - 149 => Some(Country::MK), - 150 => Some(Country::ML), - 151 => Some(Country::MM), - 152 => Some(Country::MN), - 153 => Some(Country::MO), - 154 => Some(Country::MP), - 155 => Some(Country::MQ), - 156 => Some(Country::MR), - 157 => Some(Country::MS), - 158 => Some(Country::MT), - 159 => Some(Country::MU), - 160 => Some(Country::MV), - 161 => Some(Country::MW), - 162 => Some(Country::MX), - 163 => Some(Country::MY), - 164 => Some(Country::MZ), - 165 => Some(Country::NA), - 166 => Some(Country::NC), - 167 => Some(Country::NE), - 168 => Some(Country::NF), - 169 => Some(Country::NG), - 170 => Some(Country::NI), - 171 => Some(Country::NL), - 172 => Some(Country::NO), - 173 => Some(Country::NP), - 174 => Some(Country::NR), - 175 => Some(Country::NU), - 176 => Some(Country::NZ), - 177 => Some(Country::OM), - 178 => Some(Country::PA), - 179 => Some(Country::PE), - 180 => Some(Country::PF), - 181 => Some(Country::PG), - 182 => Some(Country::PH), - 183 => Some(Country::PK), - 184 => Some(Country::PL), - 185 => Some(Country::PM), - 186 => Some(Country::PN), - 187 => Some(Country::PR), - 188 => Some(Country::PS), - 189 => Some(Country::PT), - 190 => Some(Country::PW), - 191 => Some(Country::PY), - 192 => Some(Country::QA), - 193 => Some(Country::RE), - 194 => Some(Country::RO), - 195 => Some(Country::RS), - 196 => Some(Country::RU), - 197 => Some(Country::RW), - 198 => Some(Country::SA), - 199 => Some(Country::SB), - 200 => Some(Country::SC), - 201 => Some(Country::SD), - 202 => Some(Country::SE), - 203 => Some(Country::SG), - 204 => Some(Country::SH), - 205 => Some(Country::SI), - 206 => Some(Country::SJ), - 207 => Some(Country::SK), - 208 => Some(Country::SL), - 209 => Some(Country::SM), - 210 => Some(Country::SN), - 211 => Some(Country::SO), - 212 => Some(Country::SR), - 213 => Some(Country::SS), - 214 => Some(Country::ST), - 215 => Some(Country::SV), - 216 => Some(Country::SX), - 217 => Some(Country::SY), - 218 => Some(Country::SZ), - 219 => Some(Country::TC), - 220 => Some(Country::TD), - 221 => Some(Country::TF), - 222 => Some(Country::TG), - 223 => Some(Country::TH), - 224 => Some(Country::TJ), - 225 => Some(Country::TK), - 226 => Some(Country::TL), - 227 => Some(Country::TM), - 228 => Some(Country::TN), - 229 => Some(Country::TO), - 230 => Some(Country::TR), - 231 => Some(Country::TT), - 232 => Some(Country::TV), - 233 => Some(Country::TW), - 234 => Some(Country::TZ), - 235 => Some(Country::UA), - 236 => Some(Country::UG), - 237 => Some(Country::UM), - 238 => Some(Country::US), - 239 => Some(Country::UY), - 240 => Some(Country::UZ), - 241 => Some(Country::VA), - 242 => Some(Country::VC), - 243 => Some(Country::VE), - 244 => Some(Country::VG), - 245 => Some(Country::VI), - 246 => Some(Country::VN), - 247 => Some(Country::VU), - 248 => Some(Country::WF), - 249 => Some(Country::WS), - 250 => Some(Country::XX), - 251 => Some(Country::YE), - 252 => Some(Country::YT), - 253 => Some(Country::ZA), - 254 => Some(Country::ZM), - 255 => Some(Country::ZW), - _ => None, - } - } -} - -impl rustc_serialize::Encodable for Country { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as u8).encode(s) - } -} - -impl rustc_serialize::Decodable for Country { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_u8(try!(d.read_u8())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from u8")), - } - } -} - -impl ser::Serialize for Country { - #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: ser::Serializer, - { - serializer.visit_u8(*self as u8) - } -} - -impl de::Deserialize for Country { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::impls::PrimitiveVisitor::new()) - } -} - -#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable, Serialize, Deserialize)] -struct Log { - timestamp: i64, - zone_id: u32, - zone_plan: ZonePlan, - http: Http, - origin: Origin, - country: Country, - cache_status: CacheStatus, - server_ip: String, - server_name: String, - remote_ip: String, - bytes_dlv: u64, - ray_id: String, -} - -impl Log { - fn new() -> Log { - Log { - timestamp: 2837513946597, - zone_id: 123456, - zone_plan: ZonePlan::FREE, - http: Http { - protocol: HttpProtocol::HTTP11, - status: 200, - host_status: 503, - up_status: 520, - method: HttpMethod::GET, - content_type: "text/html".to_string(), - user_agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36".to_string(), - referer: "https://www.cloudflare.com/".to_string(), - request_uri: "/cdn-cgi/trace".to_string(), - }, - origin: Origin { - ip: "1.2.3.4".to_string(), - port: 8000, - hostname: "www.example.com".to_string(), - protocol: OriginProtocol::HTTPS, - }, - country: Country::US, - cache_status: CacheStatus::Hit, - server_ip: "192.168.1.1".to_string(), - server_name: "metal.cloudflare.com".to_string(), - remote_ip: "10.1.2.3".to_string(), - bytes_dlv: 123456, - ray_id: "10c73629cce30078-LAX".to_string(), - } - } -} - -macro_rules! likely( - ($val:expr) => { - { - extern { - #[link_name = "llvm.expect.i8"] - fn expect(val: u8, expected_val: u8) -> u8; - } - let x: bool = $val; - unsafe { expect(x as u8, 1) != 0 } - } - } -); - -macro_rules! unlikely( - ($val:expr) => { - { - extern { - #[link_name = "llvm.expect.i8"] - fn expect(val: u8, expected_val: u8) -> u8; - } - let x: bool = $val; - unsafe { expect(x as u8, 0) != 0 } - } - } -); - -struct MyMemWriter0 { - buf: Vec, -} - -impl MyMemWriter0 { - pub fn with_capacity(cap: usize) -> MyMemWriter0 { - MyMemWriter0 { - buf: Vec::with_capacity(cap) - } - } -} - - -impl Write for MyMemWriter0 { - #[cfg(feature = "nightly")] - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - self.buf.push_all(buf); - Ok(buf.len()) - } - - #[cfg(not(feature = "nightly"))] - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - self.buf.extend(buf.iter().cloned()); - Ok(buf.len()) - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -struct MyMemWriter1 { - buf: Vec, -} - -impl MyMemWriter1 { - pub fn with_capacity(cap: usize) -> MyMemWriter1 { - MyMemWriter1 { - buf: Vec::with_capacity(cap) - } - } -} - -// LLVM isn't yet able to lower `Vec::push_all` into a memcpy, so this helps -// MemWriter eke out that last bit of performance. -#[inline] -fn push_all_bytes(dst: &mut Vec, src: &[u8]) { - let dst_len = dst.len(); - let src_len = src.len(); - - dst.reserve(src_len); - - unsafe { - // we would have failed if `reserve` overflowed. - dst.set_len(dst_len + src_len); - - ::std::ptr::copy_nonoverlapping( - src.as_ptr(), - dst.as_mut_ptr().offset(dst_len as isize), - src_len); - } -} - -impl Write for MyMemWriter1 { - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - push_all_bytes(&mut self.buf, buf); - Ok(buf.len()) - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -const JSON_STR: &'static str = r#"{"timestamp":2837513946597,"zone_id":123456,"zone_plan":1,"http":{"protocol":2,"status":200,"host_status":503,"up_status":520,"method":1,"content_type":"text/html","user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36","referer":"https://www.cloudflare.com/","request_uri":"/cdn-cgi/trace"},"origin":{"ip":"1.2.3.4","port":8000,"hostname":"www.example.com","protocol":2},"country":238,"cache_status":3,"server_ip":"192.168.1.1","server_name":"metal.cloudflare.com","remote_ip":"10.1.2.3","bytes_dlv":123456,"ray_id":"10c73629cce30078-LAX"}"#; - -#[test] -fn test_encoder() { - use rustc_serialize::Encodable; - - let log = Log::new(); - - let mut wr = String::with_capacity(1024); - - { - let mut encoder = rustc_serialize::json::Encoder::new(&mut wr); - log.encode(&mut encoder).unwrap() - } - - assert_eq!(&wr, &JSON_STR); -} - -#[bench] -fn bench_encoder(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = String::with_capacity(1024); - - { - let mut encoder = rustc_serialize::json::Encoder::new(&mut wr); - log.encode(&mut encoder).unwrap(); - } - - b.bytes = wr.len() as u64; - - b.iter(|| { - wr.clear(); - - let mut encoder = rustc_serialize::json::Encoder::new(&mut wr); - log.encode(&mut encoder).unwrap() - }); -} - -#[test] -fn test_serializer() { - let log = Log::new(); - let json = serde_json::to_vec(&log).unwrap(); - assert_eq!(json, JSON_STR.as_bytes()); -} - -#[bench] -fn bench_serializer(b: &mut Bencher) { - let log = Log::new(); - let json = serde_json::to_vec(&log).unwrap(); - b.bytes = json.len() as u64; - - b.iter(|| { - serde_json::to_vec(&log).unwrap() - }); -} - -#[test] -fn test_serializer_vec() { - let log = Log::new(); - let wr = Vec::with_capacity(1024); - let mut serializer = serde_json::Serializer::new(wr); - log.serialize(&mut serializer).unwrap(); - - let json = serializer.into_inner(); - assert_eq!(&json, &JSON_STR.as_bytes()); -} - -#[bench] -fn bench_serializer_vec(b: &mut Bencher) { - let log = Log::new(); - let json = serde_json::to_vec(&log).unwrap(); - b.bytes = json.len() as u64; - - let mut wr = Vec::with_capacity(1024); - - b.iter(|| { - wr.clear(); - - let mut serializer = serde_json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let json = serializer.into_inner(); - black_box(json); - }); -} - -#[bench] -fn bench_serializer_slice(b: &mut Bencher) { - let log = Log::new(); - let json = serde_json::to_vec(&log).unwrap(); - b.bytes = json.len() as u64; - - let mut buf = [0; 1024]; - - b.iter(|| { - for item in buf.iter_mut(){ *item = 0; } - let mut wr = &mut buf[..]; - - let mut serializer = serde_json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let json = serializer.into_inner(); - black_box(json); - }); -} - -#[test] -fn test_serializer_my_mem_writer0() { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - - { - let mut serializer = serde_json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let json = serializer.into_inner(); - black_box(json); - } - - assert_eq!(&wr.buf, &JSON_STR.as_bytes()); -} - -#[bench] -fn bench_serializer_my_mem_writer0(b: &mut Bencher) { - let log = Log::new(); - let json = serde_json::to_vec(&log).unwrap(); - b.bytes = json.len() as u64; - - let mut wr = MyMemWriter0::with_capacity(1024); - - b.iter(|| { - wr.buf.clear(); - - let mut serializer = serde_json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let json = serializer.into_inner(); - black_box(json); - }); -} - -#[test] -fn test_serializer_my_mem_writer1() { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - - { - let mut serializer = serde_json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let json = serializer.into_inner(); - black_box(json); - } - - assert_eq!(&wr.buf, &JSON_STR.as_bytes()); -} - -#[bench] -fn bench_serializer_my_mem_writer1(b: &mut Bencher) { - let log = Log::new(); - let json = serde_json::to_vec(&log).unwrap(); - b.bytes = json.len() as u64; - - let mut wr = MyMemWriter1::with_capacity(1024); - - b.iter(|| { - wr.buf.clear(); - - let mut serializer = serde_json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let json = serializer.into_inner(); - black_box(json); - }); -} - -#[bench] -fn bench_copy(b: &mut Bencher) { - let json = JSON_STR.as_bytes().to_vec(); - b.bytes = json.len() as u64; - - b.iter(|| { - JSON_STR.as_bytes().to_vec() - }); -} - -fn manual_serialize_no_escape(wr: &mut W, log: &Log) { - wr.write(b"{\"timestamp\":").unwrap(); - (write!(wr, "{}", log.timestamp)).unwrap(); - wr.write(b",\"zone_id\":").unwrap(); - (write!(wr, "{}", log.zone_id)).unwrap(); - wr.write(b",\"zone_plan\":").unwrap(); - (write!(wr, "{}", log.zone_plan as usize)).unwrap(); - - wr.write(b",\"http\":{\"protocol\":").unwrap(); - (write!(wr, "{}", log.http.protocol as usize)).unwrap(); - wr.write(b",\"status\":").unwrap(); - (write!(wr, "{}", log.http.status)).unwrap(); - wr.write(b",\"host_status\":").unwrap(); - (write!(wr, "{}", log.http.host_status)).unwrap(); - wr.write(b",\"up_status\":").unwrap(); - (write!(wr, "{}", log.http.up_status)).unwrap(); - wr.write(b",\"method\":").unwrap(); - (write!(wr, "{}", log.http.method as usize)).unwrap(); - wr.write(b",\"content_type\":").unwrap(); - (write!(wr, "\"{}\"", log.http.content_type)).unwrap(); - wr.write(b",\"user_agent\":").unwrap(); - (write!(wr, "\"{}\"", log.http.user_agent)).unwrap(); - wr.write(b",\"referer\":").unwrap(); - (write!(wr, "\"{}\"", log.http.referer)).unwrap(); - wr.write(b",\"request_uri\":").unwrap(); - (write!(wr, "\"{}\"", log.http.request_uri)).unwrap(); - - wr.write(b"},\"origin\":{").unwrap(); - - wr.write(b"\"ip\":").unwrap(); - (write!(wr, "\"{}\"", log.origin.ip)).unwrap(); - wr.write(b",\"port\":").unwrap(); - (write!(wr, "{}", log.origin.port)).unwrap(); - wr.write(b",\"hostname\":").unwrap(); - (write!(wr, "\"{}\"", log.origin.hostname)).unwrap(); - - wr.write(b",\"protocol\":").unwrap(); - (write!(wr, "{}", log.origin.protocol as usize)).unwrap(); - - wr.write(b"},\"country\":").unwrap(); - (write!(wr, "{}", log.country as usize)).unwrap(); - wr.write(b",\"cache_status\":").unwrap(); - (write!(wr, "{}", log.cache_status as usize)).unwrap(); - wr.write(b",\"server_ip\":").unwrap(); - (write!(wr, "\"{}\"", log.server_ip)).unwrap(); - wr.write(b",\"server_name\":").unwrap(); - (write!(wr, "\"{}\"", log.server_name)).unwrap(); - wr.write(b",\"remote_ip\":").unwrap(); - (write!(wr, "\"{}\"", log.remote_ip)).unwrap(); - wr.write(b",\"bytes_dlv\":").unwrap(); - (write!(wr, "{}", log.bytes_dlv)).unwrap(); - - wr.write(b",\"ray_id\":").unwrap(); - (write!(wr, "\"{}\"", log.ray_id)).unwrap(); - wr.write(b"}").unwrap(); -} - -fn manual_serialize_escape(wr: &mut W, log: &Log) { - wr.write_all(b"{").unwrap(); - escape_str(wr, "timestamp").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.timestamp)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "zone_id").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.zone_id)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "zone_plan").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.zone_plan as isize)).unwrap(); - - wr.write_all(b",").unwrap(); - escape_str(wr, "http").unwrap(); - wr.write_all(b":{").unwrap(); - escape_str(wr, "protocol").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.protocol as usize)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "status").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.status)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "host_status").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.host_status)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "up_status").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.up_status)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "method").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.method as usize)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "content_type").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.http.content_type).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "user_agent").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.http.user_agent).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "referer").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.http.referer).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "request_uri").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.http.request_uri).unwrap(); - - wr.write_all(b"},").unwrap(); - escape_str(wr, "origin").unwrap(); - wr.write_all(b":{").unwrap(); - - escape_str(wr, "ip").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.origin.ip).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "port").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.origin.port)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "hostname").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.origin.hostname).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "protocol").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.origin.protocol as usize)).unwrap(); - - wr.write_all(b"},").unwrap(); - escape_str(wr, "country").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.country as usize)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "cache_status").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.cache_status as usize)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "server_ip").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.server_ip).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "server_name").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.server_name).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "remote_ip").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.remote_ip).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "bytes_dlv").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.bytes_dlv)).unwrap(); - - wr.write_all(b",").unwrap(); - escape_str(wr, "ray_id").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.ray_id).unwrap(); - wr.write_all(b"}").unwrap(); -} - -#[test] -fn test_manual_serialize_vec_no_escape() { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - - let json = String::from_utf8(wr).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_vec_no_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - b.bytes = wr.len() as u64; - - b.iter(|| { - wr.clear(); - manual_serialize_no_escape(&mut wr, &log) - }); -} - -#[test] -fn test_manual_serialize_vec_escape() { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - - let json = String::from_utf8(wr).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_vec_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - b.bytes = wr.len() as u64; - - b.iter(|| { - wr.clear(); - - manual_serialize_escape(&mut wr, &log) - }); -} - -#[test] -fn test_manual_serialize_my_mem_writer0_no_escape() { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1000); - manual_serialize_no_escape(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_my_mem_writer0_no_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - manual_serialize_no_escape(&mut wr, &log) - }); -} - -#[test] -fn test_manual_serialize_my_mem_writer0_escape() { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_my_mem_writer0_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - manual_serialize_escape(&mut wr, &log) - }); -} - -#[test] -fn test_manual_serialize_my_mem_writer1_no_escape() { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_my_mem_writer1_no_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - manual_serialize_no_escape(&mut wr, &log) - }); -} - -#[test] -fn test_manual_serialize_my_mem_writer1_escape() { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_my_mem_writer1_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - manual_serialize_escape(&mut wr, &log) - }); -} - -#[bench] -fn bench_decoder(b: &mut Bencher) { - use rustc_serialize::json::Json; - - b.bytes = JSON_STR.len() as u64; - - b.iter(|| { - let json = Json::from_str(JSON_STR).unwrap(); - let mut decoder = rustc_serialize::json::Decoder::new(json); - let log: Log = rustc_serialize::Decodable::decode(&mut decoder).unwrap(); - log - }); -} - -#[bench] -fn bench_deserializer(b: &mut Bencher) { - b.bytes = JSON_STR.len() as u64; - - b.iter(|| { - let log: Log = serde_json::from_str(JSON_STR).unwrap(); - log - }); -} diff --git a/serde_tests/benches/bench_map.rs b/serde_tests/benches/bench_map.rs index 2f5b1bca..71d0ab92 100644 --- a/serde_tests/benches/bench_map.rs +++ b/serde_tests/benches/bench_map.rs @@ -417,14 +417,14 @@ fn bench_decoder_100(b: &mut Bencher) { }) } -fn run_deserializer< - D: Deserializer, - E: Debug, - T: Clone + PartialEq + Debug + Deserialize ->(mut d: D, value: T) { - let v: T = Deserialize::deserialize(&mut d).unwrap(); +fn run_deserializer(mut d: D, value: T) + where D: Deserializer, + D::Error: Debug + PartialEq, + T: Clone + PartialEq + Debug + Deserialize +{ + let v = T::deserialize(&mut d); - assert_eq!(value, v); + assert_eq!(Ok(value), v); } #[bench] diff --git a/serde_tests/benches/bench_vec.rs b/serde_tests/benches/bench_vec.rs index 450d3f1b..c0ec800c 100644 --- a/serde_tests/benches/bench_vec.rs +++ b/serde_tests/benches/bench_vec.rs @@ -504,14 +504,14 @@ fn run_decoder< assert_eq!(Ok(value), v); } -fn run_deserializer< - D: Deserializer, - E: Debug, - T: Clone + PartialEq + Debug + Deserialize ->(mut d: D, value: T) { - let v: T = Deserialize::deserialize(&mut d).unwrap(); +fn run_deserializer(mut d: D, value: T) + where D: Deserializer, + D::Error: Debug + PartialEq, + T: Clone + PartialEq + Debug + Deserialize +{ + let v = T::deserialize(&mut d); - assert_eq!(value, v); + assert_eq!(Ok(value), v); } #[bench] diff --git a/serde_tests/tests/test.rs b/serde_tests/tests/test.rs index 933c6b85..732c1432 100644 --- a/serde_tests/tests/test.rs +++ b/serde_tests/tests/test.rs @@ -1,4 +1,3 @@ extern crate serde; -extern crate serde_json; include!(concat!(env!("OUT_DIR"), "/test.rs")); diff --git a/serde_tests/tests/test_json.rs b/serde_tests/tests/test_json.rs deleted file mode 100644 index 1c092a97..00000000 --- a/serde_tests/tests/test_json.rs +++ /dev/null @@ -1,1363 +0,0 @@ -use std::collections::BTreeMap; -use std::f64; -use std::fmt::Debug; -use std::i64; -use std::marker::PhantomData; -use std::u64; - -use serde::de; -use serde::ser; - -use serde_json::{ - self, - Value, - from_str, - from_value, - to_value, -}; - -use serde_json::error::{Error, ErrorCode}; - -macro_rules! treemap { - ($($k:expr => $v:expr),*) => ({ - let mut _m = BTreeMap::new(); - $(_m.insert($k, $v);)* - _m - }) -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -enum Animal { - Dog, - Frog(String, Vec), - Cat { age: usize, name: String }, - AntHive(Vec), -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -struct Inner { - a: (), - b: usize, - c: Vec, -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -struct Outer { - inner: Vec, -} - -fn test_encode_ok(errors: &[(T, &str)]) - where T: PartialEq + Debug + ser::Serialize, -{ - for &(ref value, out) in errors { - let out = out.to_string(); - - let s = serde_json::to_string(value).unwrap(); - assert_eq!(s, out); - - let v = to_value(&value); - let s = serde_json::to_string(&v).unwrap(); - assert_eq!(s, out); - } -} - -fn test_pretty_encode_ok(errors: &[(T, &str)]) - where T: PartialEq + Debug + ser::Serialize, -{ - for &(ref value, out) in errors { - let out = out.to_string(); - - let s = serde_json::to_string_pretty(value).unwrap(); - assert_eq!(s, out); - - let v = to_value(&value); - let s = serde_json::to_string_pretty(&v).unwrap(); - assert_eq!(s, out); - } -} - -#[test] -fn test_write_null() { - let tests = &[ - ((), "null"), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_u64() { - let tests = &[ - (3u64, "3"), - (u64::MAX, &u64::MAX.to_string()), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_i64() { - let tests = &[ - (3i64, "3"), - (-2i64, "-2"), - (-1234i64, "-1234"), - (i64::MIN, &i64::MIN.to_string()), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_f64() { - let min_string = format!("{:?}", f64::MIN); - let max_string = format!("{:?}", f64::MAX); - let epsilon_string = format!("{:?}", f64::EPSILON); - - let tests = &[ - (3.0, "3"), - (3.1, "3.1"), - (-1.5, "-1.5"), - (0.5, "0.5"), - (f64::MIN, &min_string), - (f64::MAX, &max_string), - (f64::EPSILON, &epsilon_string), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_str() { - let tests = &[ - ("", "\"\""), - ("foo", "\"foo\""), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_bool() { - let tests = &[ - (true, "true"), - (false, "false"), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_list() { - test_encode_ok(&[ - (vec![], "[]"), - (vec![true], "[true]"), - (vec![true, false], "[true,false]"), - ]); - - test_encode_ok(&[ - (vec![vec![], vec![], vec![]], "[[],[],[]]"), - (vec![vec![1, 2, 3], vec![], vec![]], "[[1,2,3],[],[]]"), - (vec![vec![], vec![1, 2, 3], vec![]], "[[],[1,2,3],[]]"), - (vec![vec![], vec![], vec![1, 2, 3]], "[[],[],[1,2,3]]"), - ]); - - test_pretty_encode_ok(&[ - ( - vec![vec![], vec![], vec![]], - concat!( - "[\n", - " [],\n", - " [],\n", - " []\n", - "]" - ), - ), - ( - vec![vec![1, 2, 3], vec![], vec![]], - concat!( - "[\n", - " [\n", - " 1,\n", - " 2,\n", - " 3\n", - " ],\n", - " [],\n", - " []\n", - "]" - ), - ), - ( - vec![vec![], vec![1, 2, 3], vec![]], - concat!( - "[\n", - " [],\n", - " [\n", - " 1,\n", - " 2,\n", - " 3\n", - " ],\n", - " []\n", - "]" - ), - ), - ( - vec![vec![], vec![], vec![1, 2, 3]], - concat!( - "[\n", - " [],\n", - " [],\n", - " [\n", - " 1,\n", - " 2,\n", - " 3\n", - " ]\n", - "]" - ), - ), - ]); - - test_pretty_encode_ok(&[ - (vec![], "[]"), - ( - vec![true], - concat!( - "[\n", - " true\n", - "]" - ), - ), - ( - vec![true, false], - concat!( - "[\n", - " true,\n", - " false\n", - "]" - ), - ), - ]); - - let long_test_list = Value::Array(vec![ - Value::Bool(false), - Value::Null, - Value::Array(vec![Value::String("foo\nbar".to_string()), Value::F64(3.5)])]); - - test_encode_ok(&[ - ( - long_test_list.clone(), - "[false,null,[\"foo\\nbar\",3.5]]", - ), - ]); - - test_pretty_encode_ok(&[ - ( - long_test_list, - concat!( - "[\n", - " false,\n", - " null,\n", - " [\n", - " \"foo\\nbar\",\n", - " 3.5\n", - " ]\n", - "]" - ), - ) - ]); -} - -#[test] -fn test_write_object() { - test_encode_ok(&[ - (treemap!(), "{}"), - (treemap!("a".to_string() => true), "{\"a\":true}"), - ( - treemap!( - "a".to_string() => true, - "b".to_string() => false - ), - "{\"a\":true,\"b\":false}"), - ]); - - test_encode_ok(&[ - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "{\"a\":{},\"b\":{},\"c\":{}}", - ), - ( - treemap![ - "a".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "{\"a\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"b\":{},\"c\":{}}", - ), - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "c".to_string() => treemap![] - ], - "{\"a\":{},\"b\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"c\":{}}", - ), - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![], - "c".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ] - ], - "{\"a\":{},\"b\":{},\"c\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}}}", - ), - ]); - - test_pretty_encode_ok(&[ - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - concat!( - "{\n", - " \"a\": {},\n", - " \"b\": {},\n", - " \"c\": {}\n", - "}", - ), - ), - ( - treemap![ - "a".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - concat!( - "{\n", - " \"a\": {\n", - " \"a\": {\n", - " \"a\": [\n", - " 1,\n", - " 2,\n", - " 3\n", - " ]\n", - " },\n", - " \"b\": {},\n", - " \"c\": {}\n", - " },\n", - " \"b\": {},\n", - " \"c\": {}\n", - "}" - ), - ), - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "c".to_string() => treemap![] - ], - concat!( - "{\n", - " \"a\": {},\n", - " \"b\": {\n", - " \"a\": {\n", - " \"a\": [\n", - " 1,\n", - " 2,\n", - " 3\n", - " ]\n", - " },\n", - " \"b\": {},\n", - " \"c\": {}\n", - " },\n", - " \"c\": {}\n", - "}" - ), - ), - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![], - "c".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ] - ], - concat!( - "{\n", - " \"a\": {},\n", - " \"b\": {},\n", - " \"c\": {\n", - " \"a\": {\n", - " \"a\": [\n", - " 1,\n", - " 2,\n", - " 3\n", - " ]\n", - " },\n", - " \"b\": {},\n", - " \"c\": {}\n", - " }\n", - "}" - ), - ), - ]); - - test_pretty_encode_ok(&[ - (treemap!(), "{}"), - ( - treemap!("a".to_string() => true), - concat!( - "{\n", - " \"a\": true\n", - "}" - ), - ), - ( - treemap!( - "a".to_string() => true, - "b".to_string() => false - ), - concat!( - "{\n", - " \"a\": true,\n", - " \"b\": false\n", - "}" - ), - ), - ]); - - let complex_obj = Value::Object(treemap!( - "b".to_string() => Value::Array(vec![ - Value::Object(treemap!("c".to_string() => Value::String("\x0c\r".to_string()))), - Value::Object(treemap!("d".to_string() => Value::String("".to_string()))) - ]) - )); - - test_encode_ok(&[ - ( - complex_obj.clone(), - "{\ - \"b\":[\ - {\"c\":\"\\f\\r\"},\ - {\"d\":\"\"}\ - ]\ - }" - ), - ]); - - test_pretty_encode_ok(&[ - ( - complex_obj.clone(), - concat!( - "{\n", - " \"b\": [\n", - " {\n", - " \"c\": \"\\f\\r\"\n", - " },\n", - " {\n", - " \"d\": \"\"\n", - " }\n", - " ]\n", - "}" - ), - ) - ]); -} - -#[test] -fn test_write_tuple() { - test_encode_ok(&[ - ( - (5,), - "[5]", - ), - ]); - - test_pretty_encode_ok(&[ - ( - (5,), - concat!( - "[\n", - " 5\n", - "]" - ), - ), - ]); - - test_encode_ok(&[ - ( - (5, (6, "abc")), - "[5,[6,\"abc\"]]", - ), - ]); - - test_pretty_encode_ok(&[ - ( - (5, (6, "abc")), - concat!( - "[\n", - " 5,\n", - " [\n", - " 6,\n", - " \"abc\"\n", - " ]\n", - "]" - ), - ), - ]); -} - -#[test] -fn test_write_enum() { - test_encode_ok(&[ - ( - Animal::Dog, - "{\"Dog\":[]}", - ), - ( - Animal::Frog("Henry".to_string(), vec![]), - "{\"Frog\":[\"Henry\",[]]}", - ), - ( - Animal::Frog("Henry".to_string(), vec![349]), - "{\"Frog\":[\"Henry\",[349]]}", - ), - ( - Animal::Frog("Henry".to_string(), vec![349, 102]), - "{\"Frog\":[\"Henry\",[349,102]]}", - ), - ( - Animal::Cat { age: 5, name: "Kate".to_string() }, - "{\"Cat\":{\"age\":5,\"name\":\"Kate\"}}" - ), - ( - Animal::AntHive(vec!["Bob".to_string(), "Stuart".to_string()]), - "{\"AntHive\":[\"Bob\",\"Stuart\"]}", - ), - ]); - - test_pretty_encode_ok(&[ - ( - Animal::Dog, - concat!( - "{\n", - " \"Dog\": []\n", - "}" - ), - ), - ( - Animal::Frog("Henry".to_string(), vec![]), - concat!( - "{\n", - " \"Frog\": [\n", - " \"Henry\",\n", - " []\n", - " ]\n", - "}" - ), - ), - ( - Animal::Frog("Henry".to_string(), vec![349]), - concat!( - "{\n", - " \"Frog\": [\n", - " \"Henry\",\n", - " [\n", - " 349\n", - " ]\n", - " ]\n", - "}" - ), - ), - ( - Animal::Frog("Henry".to_string(), vec![349, 102]), - concat!( - "{\n", - " \"Frog\": [\n", - " \"Henry\",\n", - " [\n", - " 349,\n", - " 102\n", - " ]\n", - " ]\n", - "}" - ), - ), - ]); -} - -#[test] -fn test_write_option() { - test_encode_ok(&[ - (None, "null"), - (Some("jodhpurs"), "\"jodhpurs\""), - ]); - - test_encode_ok(&[ - (None, "null"), - (Some(vec!["foo", "bar"]), "[\"foo\",\"bar\"]"), - ]); - - test_pretty_encode_ok(&[ - (None, "null"), - (Some("jodhpurs"), "\"jodhpurs\""), - ]); - - test_pretty_encode_ok(&[ - (None, "null"), - ( - Some(vec!["foo", "bar"]), - concat!( - "[\n", - " \"foo\",\n", - " \"bar\"\n", - "]" - ), - ), - ]); -} - -fn test_parse_ok(errors: Vec<(&str, T)>) - where T: Clone + Debug + PartialEq + ser::Serialize + de::Deserialize, -{ - for (s, value) in errors { - let v: T = from_str(s).unwrap(); - assert_eq!(v, value.clone()); - - // Make sure we can deserialize into a `Value`. - let json_value: Value = from_str(s).unwrap(); - assert_eq!(json_value, to_value(&value)); - - // Make sure we can deserialize from a `Value`. - let v: T = from_value(json_value.clone()).unwrap(); - assert_eq!(v, value); - - // Make sure we can round trip back to `Value`. - let json_value2: Value = from_value(json_value.clone()).unwrap(); - assert_eq!(json_value2, json_value); - } -} - -// FIXME (#5527): these could be merged once UFCS is finished. -fn test_parse_err(errors: Vec<(&'static str, Error)>) - where T: Debug + PartialEq + de::Deserialize, -{ - for (s, err) in errors { - match (err, from_str::(s).unwrap_err()) { - ( - Error::SyntaxError(expected_code, expected_line, expected_col), - Error::SyntaxError(actual_code, actual_line, actual_col), - ) => { - assert_eq!( - (expected_code, expected_line, expected_col), - (actual_code, actual_line, actual_col) - ) - } - (expected_err, actual_err) => { - panic!("unexpected errors {} != {}", expected_err, actual_err) - } - } - } -} - -#[test] -fn test_parse_null() { - test_parse_err::<()>(vec![ - ("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)), - ("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)), - ("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)), - ]); - - test_parse_ok(vec![ - ("null", ()), - ]); -} - -#[test] -fn test_parse_bool() { - test_parse_err::(vec![ - ("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)), - ("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)), - ("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)), - ("faz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)), - ("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)), - ("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)), - ]); - - test_parse_ok(vec![ - ("true", true), - (" true ", true), - ("false", false), - (" false ", false), - ]); -} - -#[test] -fn test_parse_number_errors() { - test_parse_err::(vec![ - ("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)), - (".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)), - ("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 1)), - ("00", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), - ("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), - ("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), - ("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)), - ("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)), - ("1e777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 22)), - ]); -} - -#[test] -fn test_parse_i64() { - test_parse_ok(vec![ - ("-2", -2), - ("-1234", -1234), - (" -1234 ", -1234), - (&i64::MIN.to_string(), i64::MIN), - (&i64::MAX.to_string(), i64::MAX), - ]); -} - -#[test] -fn test_parse_u64() { - test_parse_ok(vec![ - ("0", 0u64), - ("3", 3u64), - ("1234", 1234), - (&u64::MAX.to_string(), u64::MAX), - ]); -} - -#[test] -fn test_parse_f64() { - test_parse_ok(vec![ - ("0.0", 0.0f64), - ("3.0", 3.0f64), - ("3.00", 3.0f64), - ("3.1", 3.1), - ("-1.2", -1.2), - ("0.4", 0.4), - ("0.4e5", 0.4e5), - ("0.4e+5", 0.4e5), - ("0.4e15", 0.4e15), - ("0.4e+15", 0.4e15), - ("0.4e-01", 0.4e-1), - (" 0.4e-01 ", 0.4e-1), - ("0.4e-001", 0.4e-1), - ("0.4e-0", 0.4e0), - ("0.00e00", 0.0), - ("0.00e+00", 0.0), - ("0.00e-00", 0.0), - (&format!("{:?}", (i64::MIN as f64) - 1.0), (i64::MIN as f64) - 1.0), - (&format!("{:?}", (u64::MAX as f64) + 1.0), (u64::MAX as f64) + 1.0), - (&format!("{:?}", f64::EPSILON), f64::EPSILON), - ]); -} - -#[test] -fn test_parse_string() { - test_parse_err::(vec![ - ("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 1)), - ("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 4)), - ("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)), - ]); - - test_parse_ok(vec![ - ("\"\"", "".to_string()), - ("\"foo\"", "foo".to_string()), - (" \"foo\" ", "foo".to_string()), - ("\"\\\"\"", "\"".to_string()), - ("\"\\b\"", "\x08".to_string()), - ("\"\\n\"", "\n".to_string()), - ("\"\\r\"", "\r".to_string()), - ("\"\\t\"", "\t".to_string()), - ("\"\\u12ab\"", "\u{12ab}".to_string()), - ("\"\\uAB12\"", "\u{AB12}".to_string()), - ]); -} - -#[test] -fn test_parse_list() { - test_parse_err::>(vec![ - ("[", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 1)), - ("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 2)), - ("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 2)), - ("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)), - ("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)), - ("[1 2]", Error::SyntaxError(ErrorCode::ExpectedListCommaOrEnd, 1, 4)), - ("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)), - ]); - - test_parse_ok(vec![ - ("[]", vec![]), - ("[ ]", vec![]), - ("[null]", vec![()]), - (" [ null ] ", vec![()]), - ]); - - test_parse_ok(vec![ - ("[true]", vec![true]), - ]); - - test_parse_ok(vec![ - ("[3,1]", vec![3u64, 1]), - (" [ 3 , 1 ] ", vec![3, 1]), - ]); - - test_parse_ok(vec![ - ("[[3], [1, 2]]", vec![vec![3u64], vec![1, 2]]), - ]); - - test_parse_ok(vec![ - ("[1]", (1u64,)), - ]); - - test_parse_ok(vec![ - ("[1, 2]", (1u64, 2u64)), - ]); - - test_parse_ok(vec![ - ("[1, 2, 3]", (1u64, 2u64, 3u64)), - ]); - - test_parse_ok(vec![ - ("[1, [2, 3]]", (1u64, (2u64, 3u64))), - ]); - - let v: () = from_str("[]").unwrap(); - assert_eq!(v, ()); -} - -#[test] -fn test_parse_object() { - test_parse_err::>(vec![ - ("{", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 1)), - ("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 2)), - ("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)), - ("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)), - ("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 4)), - ("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)), - ("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)), - ("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 5)), - ("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)), - ("{\"a\":1 1", Error::SyntaxError(ErrorCode::ExpectedObjectCommaOrEnd, 1, 8)), - ("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 7)), - ("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)), - ]); - - test_parse_ok(vec![ - ("{}", treemap!()), - ("{ }", treemap!()), - ( - "{\"a\":3}", - treemap!("a".to_string() => 3u64) - ), - ( - "{ \"a\" : 3 }", - treemap!("a".to_string() => 3) - ), - ( - "{\"a\":3,\"b\":4}", - treemap!("a".to_string() => 3, "b".to_string() => 4) - ), - ( - " { \"a\" : 3 , \"b\" : 4 } ", - treemap!("a".to_string() => 3, "b".to_string() => 4), - ), - ]); - - test_parse_ok(vec![ - ( - "{\"a\": {\"b\": 3, \"c\": 4}}", - treemap!( - "a".to_string() => treemap!( - "b".to_string() => 3u64, - "c".to_string() => 4 - ) - ), - ), - ]); -} - -#[test] -fn test_parse_struct() { - test_parse_err::(vec![ - ("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)), - ("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 7)), - ("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 14)), - ]); - - test_parse_ok(vec![ - ( - "{ - \"inner\": [] - }", - Outer { - inner: vec![] - }, - ), - ( - "{ - \"inner\": [ - { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } - ] - }", - Outer { - inner: vec![ - Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] } - ] - }, - ), - ]); - - let v: Outer = from_str("{}").unwrap(); - - assert_eq!( - v, - Outer { - inner: vec![], - } - ); - - let v: Outer = from_str( - "[ - [ - [ null, 2, [\"abc\", \"xyz\"] ] - ] - ]").unwrap(); - - assert_eq!( - v, - Outer { - inner: vec![ - Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] } - ], - } - ); -} - -#[test] -fn test_parse_option() { - test_parse_ok(vec![ - ("null", None::), - ("\"jodhpurs\"", Some("jodhpurs".to_string())), - ]); - - #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] - struct Foo { - x: Option, - } - - let value: Foo = from_str("{}").unwrap(); - assert_eq!(value, Foo { x: None }); - - test_parse_ok(vec![ - ("{\"x\": null}", Foo { x: None }), - ("{\"x\": 5}", Foo { x: Some(5) }), - ]); -} - -#[test] -fn test_parse_enum_errors() { - test_parse_err::(vec![ - ("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)), - ("{\"Dog\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 7)), - ("{\"Dog\":}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)), - ("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::UnknownField("unknown".to_string()), 1, 10)), - ("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)), - ("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)), - ("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 9)), - ]); -} - -#[test] -fn test_parse_enum() { - test_parse_ok(vec![ - ("{\"Dog\":[]}", Animal::Dog), - (" { \"Dog\" : [ ] } ", Animal::Dog), - ( - "{\"Frog\":[\"Henry\",[]]}", - Animal::Frog("Henry".to_string(), vec![]), - ), - ( - " { \"Frog\": [ \"Henry\" , [ 349, 102 ] ] } ", - Animal::Frog("Henry".to_string(), vec![349, 102]), - ), - ( - "{\"Cat\": {\"age\": 5, \"name\": \"Kate\"}}", - Animal::Cat { age: 5, name: "Kate".to_string() }, - ), - ( - " { \"Cat\" : { \"age\" : 5 , \"name\" : \"Kate\" } } ", - Animal::Cat { age: 5, name: "Kate".to_string() }, - ), - ( - " { \"AntHive\" : [\"Bob\", \"Stuart\"] } ", - Animal::AntHive(vec!["Bob".to_string(), "Stuart".to_string()]), - ), - ]); - - test_parse_ok(vec![ - ( - concat!( - "{", - " \"a\": {\"Dog\": []},", - " \"b\": {\"Frog\":[\"Henry\", []]}", - "}" - ), - treemap!( - "a".to_string() => Animal::Dog, - "b".to_string() => Animal::Frog("Henry".to_string(), vec![]) - ) - ), - ]); -} - -#[test] -fn test_parse_trailing_whitespace() { - test_parse_ok(vec![ - ("[1, 2] ", vec![1u64, 2]), - ("[1, 2]\n", vec![1, 2]), - ("[1, 2]\t", vec![1, 2]), - ("[1, 2]\t \n", vec![1, 2]), - ]); -} - -#[test] -fn test_multiline_errors() { - test_parse_err::>(vec![ - ("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 6)), - ]); -} - -#[test] -fn test_missing_field() { - #[derive(Debug, PartialEq, Deserialize)] - struct Foo { - x: Option, - } - - let value: Foo = from_str("{}").unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_str("{\"x\": 5}").unwrap(); - assert_eq!(value, Foo { x: Some(5) }); - - let value: Foo = from_value(Value::Object(treemap!())).unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_value(Value::Object(treemap!( - "x".to_string() => Value::I64(5) - ))).unwrap(); - assert_eq!(value, Foo { x: Some(5) }); -} - -#[test] -fn test_missing_renamed_field() { - #[derive(Debug, PartialEq, Deserialize)] - struct Foo { - #[serde(rename="y")] - x: Option, - } - - let value: Foo = from_str("{}").unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_str("{\"y\": 5}").unwrap(); - assert_eq!(value, Foo { x: Some(5) }); - - let value: Foo = from_value(Value::Object(treemap!())).unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_value(Value::Object(treemap!( - "y".to_string() => Value::I64(5) - ))).unwrap(); - assert_eq!(value, Foo { x: Some(5) }); -} - -#[test] -fn test_missing_fmt_renamed_field() { - #[derive(Debug, PartialEq, Deserialize)] - struct Foo { - #[serde(rename(json="y"))] - x: Option, - } - - let value: Foo = from_str("{}").unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_str("{\"y\": 5}").unwrap(); - assert_eq!(value, Foo { x: Some(5) }); - - let value: Foo = from_value(Value::Object(treemap!())).unwrap(); - assert_eq!(value, Foo { x: None }); - - let value : Foo = from_value(Value::Object(treemap!( - "y".to_string() => Value::I64(5) - ))).unwrap(); - assert_eq!(value, Foo { x: Some(5) }); -} - -#[test] -fn test_find_path() { - let obj: Value = serde_json::from_str(r#"{"x": {"a": 1}, "y": 2}"#).unwrap(); - - assert!(obj.find_path(&["x", "a"]).unwrap() == &Value::U64(1)); - assert!(obj.find_path(&["y"]).unwrap() == &Value::U64(2)); - assert!(obj.find_path(&["z"]).is_none()); -} - -#[test] -fn test_lookup() { - let obj: Value = serde_json::from_str(r#"{"x": {"a": 1}, "y": 2}"#).unwrap(); - - assert!(obj.lookup("x.a").unwrap() == &Value::U64(1)); - assert!(obj.lookup("y").unwrap() == &Value::U64(2)); - assert!(obj.lookup("z").is_none()); -} - -#[test] -fn test_serialize_seq_with_no_len() { - #[derive(Clone, Debug, PartialEq)] - struct MyVec(Vec); - - impl ser::Serialize for MyVec - where T: ser::Serialize, - { - #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: ser::Serializer, - { - serializer.visit_seq(ser::impls::SeqIteratorVisitor::new(self.0.iter(), None)) - } - } - - struct Visitor { - marker: PhantomData>, - } - - impl de::Visitor for Visitor - where T: de::Deserialize, - { - type Value = MyVec; - - #[inline] - fn visit_unit(&mut self) -> Result, E> - where E: de::Error, - { - Ok(MyVec(Vec::new())) - } - - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> Result, V::Error> - where V: de::SeqVisitor, - { - let mut values = Vec::new(); - - while let Some(value) = try!(visitor.visit()) { - values.push(value); - } - - try!(visitor.end()); - - Ok(MyVec(values)) - } - } - - impl de::Deserialize for MyVec - where T: de::Deserialize, - { - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: de::Deserializer, - { - deserializer.visit_map(Visitor { marker: PhantomData }) - } - } - - let mut vec = Vec::new(); - vec.push(MyVec(Vec::new())); - vec.push(MyVec(Vec::new())); - let vec: MyVec> = MyVec(vec); - - test_encode_ok(&[ - ( - vec.clone(), - "[[],[]]", - ), - ]); - - let s = serde_json::to_string_pretty(&vec).unwrap(); - assert_eq!( - s, - concat!( - "[\n", - " [\n", - " ],\n", - " [\n", - " ]\n", - "]" - ) - ); -} - -#[test] -fn test_serialize_map_with_no_len() { - #[derive(Clone, Debug, PartialEq)] - struct Map(BTreeMap); - - impl ser::Serialize for Map - where K: ser::Serialize + Ord, - V: ser::Serialize, - { - #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: ser::Serializer, - { - serializer.visit_map(ser::impls::MapIteratorVisitor::new(self.0.iter(), None)) - } - } - - struct Visitor { - marker: PhantomData>, - } - - impl de::Visitor for Visitor - where K: de::Deserialize + Eq + Ord, - V: de::Deserialize, - { - type Value = Map; - - #[inline] - fn visit_unit(&mut self) -> Result, E> - where E: de::Error, - { - Ok(Map(BTreeMap::new())) - } - - #[inline] - fn visit_map(&mut self, mut visitor: Visitor) -> Result, Visitor::Error> - where Visitor: de::MapVisitor, - { - let mut values = BTreeMap::new(); - - while let Some((key, value)) = try!(visitor.visit()) { - values.insert(key, value); - } - - try!(visitor.end()); - - Ok(Map(values)) - } - } - - impl de::Deserialize for Map - where K: de::Deserialize + Eq + Ord, - V: de::Deserialize, - { - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: de::Deserializer, - { - deserializer.visit_map(Visitor { marker: PhantomData }) - } - } - - let mut map = BTreeMap::new(); - map.insert("a", Map(BTreeMap::new())); - map.insert("b", Map(BTreeMap::new())); - let map: Map<_, Map> = Map(map); - - test_encode_ok(&[ - ( - map.clone(), - "{\"a\":{},\"b\":{}}", - ), - ]); - - let s = serde_json::to_string_pretty(&map).unwrap(); - assert_eq!( - s, - concat!( - "{\n", - " \"a\": {\n", - " },\n", - " \"b\": {\n", - " }\n", - "}" - ) - ); -} - -#[test] -fn test_deserialize_from_stream() { - use std::net; - use std::io::Read; - use std::thread; - use serde::Deserialize; - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct Message { - message: String, - } - - let l = net::TcpListener::bind("localhost:20000").unwrap(); - - thread::spawn(|| { - let l = l; - for stream in l.incoming() { - let mut stream = stream.unwrap(); - let read_stream = stream.try_clone().unwrap(); - - let mut de = serde_json::Deserializer::new(read_stream.bytes()); - let request = Message::deserialize(&mut de).unwrap(); - let response = Message { message: request.message }; - serde_json::to_writer(&mut stream, &response).unwrap(); - } - }); - - let mut stream = net::TcpStream::connect("localhost:20000").unwrap(); - let request = Message { message: "hi there".to_string() }; - serde_json::to_writer(&mut stream, &request).unwrap(); - - let mut de = serde_json::Deserializer::new(stream.bytes()); - let response = Message::deserialize(&mut de).unwrap(); - - assert_eq!(request, response); -} - -#[test] -fn test_serialize_rejects_non_key_maps() { - let map = treemap!( - 1 => 2, - 3 => 4 - ); - - match serde_json::to_vec(&map).unwrap_err() { - serde_json::Error::SyntaxError(serde_json::ErrorCode::KeyMustBeAString, 0, 0) => {} - _ => panic!("integers used as keys"), - } -} diff --git a/serde_tests/tests/test_json_builder.rs b/serde_tests/tests/test_json_builder.rs deleted file mode 100644 index 55fcff08..00000000 --- a/serde_tests/tests/test_json_builder.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::collections::BTreeMap; - -use serde_json::value::Value; -use serde_json::builder::{ArrayBuilder, ObjectBuilder}; - -#[test] -fn test_array_builder() { - let value = ArrayBuilder::new().unwrap(); - assert_eq!(value, Value::Array(Vec::new())); - - let value = ArrayBuilder::new() - .push(1) - .push(2) - .push(3) - .unwrap(); - assert_eq!(value, Value::Array(vec!(Value::U64(1), Value::U64(2), Value::U64(3)))); - - let value = ArrayBuilder::new() - .push_array(|bld| bld.push(1).push(2).push(3)) - .unwrap(); - assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::U64(1), Value::U64(2), Value::U64(3)))))); - - let value = ArrayBuilder::new() - .push_object(|bld| - bld - .insert("a".to_string(), 1) - .insert("b".to_string(), 2)) - .unwrap(); - - let mut map = BTreeMap::new(); - map.insert("a".to_string(), Value::U64(1)); - map.insert("b".to_string(), Value::U64(2)); - assert_eq!(value, Value::Array(vec!(Value::Object(map)))); -} - -#[test] -fn test_object_builder() { - let value = ObjectBuilder::new().unwrap(); - assert_eq!(value, Value::Object(BTreeMap::new())); - - let value = ObjectBuilder::new() - .insert("a".to_string(), 1) - .insert("b".to_string(), 2) - .unwrap(); - - let mut map = BTreeMap::new(); - map.insert("a".to_string(), Value::U64(1)); - map.insert("b".to_string(), Value::U64(2)); - assert_eq!(value, Value::Object(map)); -}