From 42069ca66991d1197a81f67b4355db9ece8ec2c1 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 27 Aug 2015 20:01:09 -0700 Subject: [PATCH 1/2] Refactor tests to not use serde_json --- serde/src/de/value.rs | 1 + serde_codegen/src/ser.rs | 7 +- serde_macros/tests/test.rs | 1 - serde_tests/Cargo.toml | 1 - serde_tests/tests/macros.rs | 79 +++ serde_tests/tests/test.rs.in | 7 +- serde_tests/tests/test_annotations.rs | 139 ++++- serde_tests/tests/test_bytes.rs | 43 -- serde_tests/tests/test_de.rs | 677 ++++------------------ serde_tests/tests/test_macros.rs | 561 +++++++++--------- serde_tests/tests/test_ser.rs | 411 ++------------ serde_tests/tests/token.rs | 789 ++++++++++++++++++++++++++ 12 files changed, 1449 insertions(+), 1267 deletions(-) create mode 100644 serde_tests/tests/macros.rs create mode 100644 serde_tests/tests/token.rs diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 3492a5c1..af0716be 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -16,6 +16,7 @@ use bytes; /////////////////////////////////////////////////////////////////////////////// +#[derive(Clone, Debug, PartialEq)] pub enum Error { SyntaxError, EndOfStreamError, diff --git a/serde_codegen/src/ser.rs b/serde_codegen/src/ser.rs index 7119faca..a749926f 100644 --- a/serde_codegen/src/ser.rs +++ b/serde_codegen/src/ser.rs @@ -580,10 +580,13 @@ fn serialize_struct_visitor( ) -> (P, P) where I: Iterator>, { - let len = struct_def.fields.len(); - let field_attrs = struct_field_attrs(cx, builder, struct_def); + let len = struct_def.fields.len() - field_attrs.iter() + .fold(0, |sum, field| { + sum + if field.skip_serializing_field() { 1 } else { 0 } + }); + let arms: Vec = field_attrs.into_iter() .zip(value_exprs) .filter(|&(ref field, _)| !field.skip_serializing_field()) diff --git a/serde_macros/tests/test.rs b/serde_macros/tests/test.rs index 7e98981c..fd353e1b 100644 --- a/serde_macros/tests/test.rs +++ b/serde_macros/tests/test.rs @@ -2,7 +2,6 @@ #![plugin(serde_macros)] extern crate serde; -extern crate serde_json; extern crate test; include!("../../serde_tests/tests/test.rs.in"); diff --git a/serde_tests/Cargo.toml b/serde_tests/Cargo.toml index 2fdf5510..68356a29 100644 --- a/serde_tests/Cargo.toml +++ b/serde_tests/Cargo.toml @@ -19,7 +19,6 @@ serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-sy num = "*" rustc-serialize = "*" serde = { version = "*", path = "../serde" } -serde_json = { version = "*", path = "../serde_json" } syntex = "*" [[test]] diff --git a/serde_tests/tests/macros.rs b/serde_tests/tests/macros.rs new file mode 100644 index 00000000..069d4f26 --- /dev/null +++ b/serde_tests/tests/macros.rs @@ -0,0 +1,79 @@ +#[macro_export] +macro_rules! declare_ser_tests { + ($($name:ident { $($value:expr => $tokens:expr,)+ })+) => { + $( + #[test] + fn $name() { + $( + ::token::assert_ser_tokens(&$value, $tokens); + )+ + } + )+ + } +} + +#[macro_export] +macro_rules! btreemap { + () => { + BTreeMap::new() + }; + ($($key:expr => $value:expr),+) => { + { + let mut map = BTreeMap::new(); + $(map.insert($key, $value);)+ + map + } + } +} + +macro_rules! btreeset { + () => { + BTreeSet::new() + }; + ($($value:expr),+) => { + { + let mut set = BTreeSet::new(); + $(set.insert($value);)+ + set + } + } +} + +macro_rules! btreemap { + () => { + BTreeMap::new() + }; + ($($key:expr => $value:expr),+) => { + { + let mut map = BTreeMap::new(); + $(map.insert($key, $value);)+ + map + } + } +} + +macro_rules! hashset { + () => { + HashSet::new() + }; + ($($value:expr),+) => { + { + let mut set = HashSet::new(); + $(set.insert($value);)+ + set + } + } +} + +macro_rules! hashmap { + () => { + HashMap::new() + }; + ($($key:expr => $value:expr),+) => { + { + let mut map = HashMap::new(); + $(map.insert($key, $value);)+ + map + } + } +} diff --git a/serde_tests/tests/test.rs.in b/serde_tests/tests/test.rs.in index e6c552f3..89a1b345 100644 --- a/serde_tests/tests/test.rs.in +++ b/serde_tests/tests/test.rs.in @@ -1,7 +1,10 @@ +#[macro_use] +mod macros; + +mod token; + mod test_annotations; mod test_bytes; mod test_de; -mod test_json; -mod test_json_builder; mod test_macros; mod test_ser; diff --git a/serde_tests/tests/test_annotations.rs b/serde_tests/tests/test_annotations.rs index 9c963f8e..65508658 100644 --- a/serde_tests/tests/test_annotations.rs +++ b/serde_tests/tests/test_annotations.rs @@ -1,5 +1,6 @@ use std::default; -use serde_json; + +use token::{Token, assert_tokens, assert_ser_tokens, assert_de_tokens}; #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Default { @@ -18,7 +19,7 @@ struct Rename { #[derive(Debug, PartialEq, Serialize, Deserialize)] struct FormatRename { a1: i32, - #[serde(rename(xml= "a4", json="a5"))] + #[serde(rename(xml= "a4", token="a5"))] a2: i32, } @@ -26,7 +27,7 @@ struct FormatRename { enum SerEnum { Map { a: i8, - #[serde(rename(xml= "c", json="d"))] + #[serde(rename(xml= "c", token="d"))] b: A, }, } @@ -40,51 +41,131 @@ struct SkipSerializingFields { #[test] fn test_default() { - let deserialized_value: Default = serde_json::from_str(&"{\"a1\":1,\"a2\":2}").unwrap(); - assert_eq!(deserialized_value, Default { a1: 1, a2: 2 }); + assert_de_tokens( + &Default { a1: 1, a2: 2 }, + vec![ + Token::StructStart("Default", Some(2)), - let deserialized_value: Default = serde_json::from_str(&"{\"a1\":1}").unwrap(); - assert_eq!(deserialized_value, Default { a1: 1, a2: 0 }); + Token::MapSep, + Token::Str("a1"), + Token::I32(1), + + Token::MapSep, + Token::Str("a2"), + Token::I32(2), + + Token::MapEnd, + ] + ); + + assert_de_tokens( + &Default { a1: 1, a2: 0 }, + vec![ + Token::StructStart("Default", Some(1)), + + Token::MapSep, + Token::Str("a1"), + Token::I32(1), + + Token::MapEnd, + ] + ); } #[test] fn test_rename() { - let value = Rename { a1: 1, a2: 2 }; - let serialized_value = serde_json::to_string(&value).unwrap(); - assert_eq!(serialized_value, "{\"a1\":1,\"a3\":2}"); + assert_tokens( + &Rename { a1: 1, a2: 2 }, + vec![ + Token::StructStart("Rename", Some(2)), - let deserialized_value: Rename = serde_json::from_str(&serialized_value).unwrap(); - assert_eq!(value, deserialized_value); + Token::MapSep, + Token::Str("a1"), + Token::I32(1), + + Token::MapSep, + Token::Str("a3"), + Token::I32(2), + + Token::MapEnd, + ] + ); } #[test] fn test_format_rename() { - let value = FormatRename { a1: 1, a2: 2 }; - let serialized_value = serde_json::to_string(&value).unwrap(); - assert_eq!(serialized_value, "{\"a1\":1,\"a5\":2}"); + assert_tokens( + &FormatRename { a1: 1, a2: 2 }, + vec![ + Token::StructStart("FormatRename", Some(2)), - let deserialized_value = serde_json::from_str("{\"a1\":1,\"a5\":2}").unwrap(); - assert_eq!(value, deserialized_value); + Token::MapSep, + Token::Str("a1"), + Token::I32(1), + + Token::MapSep, + Token::Str("a5"), + Token::I32(2), + + Token::MapEnd, + ] + ); } #[test] fn test_enum_format_rename() { - let s1 = String::new(); - let value = SerEnum::Map { a: 0i8, b: s1 }; - let serialized_value = serde_json::to_string(&value).unwrap(); - let ans = "{\"Map\":{\"a\":0,\"d\":\"\"}}"; - assert_eq!(serialized_value, ans); + assert_tokens( + &SerEnum::Map { + a: 0, + b: String::new(), + }, + vec![ + Token::EnumMapStart("SerEnum", "Map", Some(2)), - let deserialized_value = serde_json::from_str(ans).unwrap(); - assert_eq!(value, deserialized_value); + Token::MapSep, + Token::Str("a"), + Token::I8(0), + + Token::MapSep, + Token::Str("d"), + Token::Str(""), + + Token::MapEnd, + ] + ); } #[test] fn test_skip_serializing_fields() { - let value = SkipSerializingFields { a: 1, b: 2 }; - let serialized_value = serde_json::to_string(&value).unwrap(); - assert_eq!(serialized_value, "{\"a\":1}"); + assert_ser_tokens( + &SkipSerializingFields { + a: 1, + b: 2, + }, + &[ + Token::StructStart("SkipSerializingFields", Some(1)), - let deserialized_value: SkipSerializingFields<_> = serde_json::from_str(&serialized_value).unwrap(); - assert_eq!(SkipSerializingFields { a: 1, b: 0 }, deserialized_value); + Token::MapSep, + Token::Str("a"), + Token::I8(1), + + Token::MapEnd, + ] + ); + + assert_de_tokens( + &SkipSerializingFields { + a: 1, + b: 0, + }, + vec![ + Token::StructStart("SkipSerializingFields", Some(1)), + + Token::MapSep, + Token::Str("a"), + Token::I8(1), + + Token::MapEnd, + ] + ); } diff --git a/serde_tests/tests/test_bytes.rs b/serde_tests/tests/test_bytes.rs index d0e8227a..1203fed4 100644 --- a/serde_tests/tests/test_bytes.rs +++ b/serde_tests/tests/test_bytes.rs @@ -1,7 +1,6 @@ use serde; use serde::Serialize; use serde::bytes::{ByteBuf, Bytes}; -use serde_json; /////////////////////////////////////////////////////////////////////////////// @@ -140,17 +139,6 @@ impl serde::Deserializer for BytesDeserializer { /////////////////////////////////////////////////////////////////////////////// -#[test] -fn test_bytes_ser_json() { - let buf = vec![]; - let bytes = Bytes::from(&buf); - assert_eq!(serde_json::to_string(&bytes).unwrap(), "[]".to_string()); - - let buf = vec![1, 2, 3]; - let bytes = Bytes::from(&buf); - assert_eq!(serde_json::to_string(&bytes).unwrap(), "[1,2,3]".to_string()); -} - #[test] fn test_bytes_ser_bytes() { let buf = vec![]; @@ -164,39 +152,8 @@ fn test_bytes_ser_bytes() { bytes.serialize(&mut ser).unwrap(); } -#[test] -fn test_byte_buf_ser_json() { - let bytes = ByteBuf::new(); - assert_eq!(serde_json::to_string(&bytes).unwrap(), "[]".to_string()); - - let bytes = ByteBuf::from(vec![1, 2, 3]); - assert_eq!(serde_json::to_string(&bytes).unwrap(), "[1,2,3]".to_string()); -} - -#[test] -fn test_byte_buf_ser_bytes() { - let bytes = ByteBuf::new(); - let mut ser = BytesSerializer::new(vec![]); - bytes.serialize(&mut ser).unwrap(); - - let bytes = ByteBuf::from(vec![1, 2, 3]); - let mut ser = BytesSerializer::new(vec![1, 2, 3]); - bytes.serialize(&mut ser).unwrap(); -} - /////////////////////////////////////////////////////////////////////////////// -#[test] -fn test_byte_buf_de_json() { - let bytes = ByteBuf::new(); - let v: ByteBuf = serde_json::from_str("[]").unwrap(); - assert_eq!(v, bytes); - - let bytes = ByteBuf::from(vec![1, 2, 3]); - let v: ByteBuf = serde_json::from_str("[1, 2, 3]").unwrap(); - assert_eq!(v, bytes); -} - #[test] fn test_byte_buf_de_bytes() { let mut de = BytesDeserializer::new(vec![]); diff --git a/serde_tests/tests/test_de.rs b/serde_tests/tests/test_de.rs index 5c944889..eebe179e 100644 --- a/serde_tests/tests/test_de.rs +++ b/serde_tests/tests/test_de.rs @@ -1,384 +1,8 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; -use std::iter; -use std::vec; -use serde::de::{self, Deserialize, Deserializer, Visitor}; +use serde::de::{Deserializer, Visitor}; -#[derive(Debug)] -enum Token { - Bool(bool), - Isize(isize), - I8(i8), - I16(i16), - I32(i32), - I64(i64), - Usize(usize), - U8(u8), - U16(u16), - U32(u32), - U64(u64), - F32(f32), - F64(f64), - Char(char), - Str(&'static str), - String(String), - Bytes(&'static [u8]), - - Option(bool), - - Name(&'static str), - - Unit, - - SeqStart(usize), - SeqSep, - SeqEnd, - - MapStart(usize), - MapSep, - MapEnd, - - EnumStart(&'static str), - EnumUnit, - EnumNewtype, - EnumSeq, - EnumMap, - EnumEnd, -} - -struct TokenDeserializer { - tokens: iter::Peekable>, -} - -impl<'a> TokenDeserializer { - fn new(tokens: Vec) -> TokenDeserializer { - TokenDeserializer { - tokens: tokens.into_iter().peekable(), - } - } -} - -#[derive(Clone, PartialEq, Debug)] -enum Error { - SyntaxError, - EndOfStreamError, - UnknownFieldError(String), - MissingFieldError(&'static str), - InvalidName(&'static str), -} - -impl de::Error for Error { - fn syntax(_: &str) -> Error { Error::SyntaxError } - - fn end_of_stream() -> Error { Error::EndOfStreamError } - - fn unknown_field(field: &str) -> Error { - Error::UnknownFieldError(field.to_string()) - } - - fn missing_field(field: &'static str) -> Error { - Error::MissingFieldError(field) - } -} - -impl Deserializer for TokenDeserializer { - type Error = Error; - - fn visit(&mut self, mut visitor: V) -> Result - where V: Visitor, - { - match self.tokens.next() { - Some(Token::Bool(v)) => visitor.visit_bool(v), - Some(Token::Isize(v)) => visitor.visit_isize(v), - Some(Token::I8(v)) => visitor.visit_i8(v), - Some(Token::I16(v)) => visitor.visit_i16(v), - Some(Token::I32(v)) => visitor.visit_i32(v), - Some(Token::I64(v)) => visitor.visit_i64(v), - Some(Token::Usize(v)) => visitor.visit_usize(v), - Some(Token::U8(v)) => visitor.visit_u8(v), - Some(Token::U16(v)) => visitor.visit_u16(v), - Some(Token::U32(v)) => visitor.visit_u32(v), - Some(Token::U64(v)) => visitor.visit_u64(v), - Some(Token::F32(v)) => visitor.visit_f32(v), - Some(Token::F64(v)) => visitor.visit_f64(v), - Some(Token::Char(v)) => visitor.visit_char(v), - Some(Token::Str(v)) => visitor.visit_str(v), - Some(Token::String(v)) => visitor.visit_string(v), - Some(Token::Bytes(v)) => visitor.visit_bytes(v), - Some(Token::Option(false)) => visitor.visit_none(), - Some(Token::Option(true)) => visitor.visit_some(self), - Some(Token::Unit) => visitor.visit_unit(), - Some(Token::SeqStart(len)) => { - visitor.visit_seq(TokenDeserializerSeqVisitor { - de: self, - len: len, - }) - } - Some(Token::MapStart(len)) => { - visitor.visit_map(TokenDeserializerMapVisitor { - de: self, - len: len, - }) - } - Some(Token::Name(_)) => self.visit(visitor), - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStreamError), - } - } - - /// Hook into `Option` deserializing so we can treat `Unit` as a - /// `None`, or a regular value as `Some(value)`. - fn visit_option(&mut self, mut visitor: V) -> Result - where V: Visitor, - { - match self.tokens.peek() { - Some(&Token::Option(false)) => { - self.tokens.next(); - visitor.visit_none() - } - Some(&Token::Option(true)) => { - self.tokens.next(); - visitor.visit_some(self) - } - Some(&Token::Unit) => { - self.tokens.next(); - visitor.visit_none() - } - Some(_) => visitor.visit_some(self), - None => Err(Error::EndOfStreamError), - } - } - - fn visit_enum(&mut self, - name: &str, - _variants: &'static [&'static str], - mut visitor: V) -> Result - where V: de::EnumVisitor, - { - match self.tokens.next() { - Some(Token::EnumStart(n)) => { - if name == n { - visitor.visit(TokenDeserializerVariantVisitor { - de: self, - }) - } else { - Err(Error::SyntaxError) - } - } - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStreamError), - } - } - - fn visit_unit_struct(&mut self, name: &str, visitor: V) -> Result - where V: de::Visitor, - { - match self.tokens.peek() { - Some(&Token::Name(n)) => { - if name == n { - self.tokens.next(); - self.visit_seq(visitor) - } else { - Err(Error::InvalidName(n)) - } - } - Some(_) => self.visit(visitor), - None => Err(Error::EndOfStreamError), - } - } - - fn visit_tuple_struct(&mut self, - name: &str, - _len: usize, - visitor: V) -> Result - where V: de::Visitor, - { - match self.tokens.peek() { - Some(&Token::Name(n)) => { - if name == n { - self.tokens.next(); - self.visit_seq(visitor) - } else { - Err(Error::InvalidName(n)) - } - } - Some(_) => self.visit_seq(visitor), - None => Err(Error::EndOfStreamError), - } - } - - fn visit_struct(&mut self, - name: &str, - _fields: &'static [&'static str], - visitor: V) -> Result - where V: de::Visitor, - { - match self.tokens.peek() { - Some(&Token::Name(n)) => { - if name == n { - self.tokens.next(); - self.visit_map(visitor) - } else { - Err(Error::InvalidName(n)) - } - } - Some(_) => self.visit_map(visitor), - None => Err(Error::EndOfStreamError), - } - } -} - -////////////////////////////////////////////////////////////////////////// - -struct TokenDeserializerSeqVisitor<'a> { - de: &'a mut TokenDeserializer, - len: usize, -} - -impl<'a> de::SeqVisitor for TokenDeserializerSeqVisitor<'a> { - type Error = Error; - - fn visit(&mut self) -> Result, Error> - where T: Deserialize, - { - match self.de.tokens.peek() { - Some(&Token::SeqSep) => { - self.len -= 1; - self.de.tokens.next(); - Ok(Some(try!(Deserialize::deserialize(self.de)))) - } - Some(&Token::SeqEnd) => Ok(None), - Some(_) => { - Err(Error::SyntaxError) - } - None => Err(Error::EndOfStreamError), - } - } - - fn end(&mut self) -> Result<(), Error> { - assert_eq!(self.len, 0); - match self.de.tokens.next() { - Some(Token::SeqEnd) => Ok(()), - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStreamError), - } - } - - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -////////////////////////////////////////////////////////////////////////// - -struct TokenDeserializerMapVisitor<'a> { - de: &'a mut TokenDeserializer, - len: usize, -} - -impl<'a> de::MapVisitor for TokenDeserializerMapVisitor<'a> { - type Error = Error; - - fn visit_key(&mut self) -> Result, Error> - where K: Deserialize, - { - match self.de.tokens.peek() { - Some(&Token::MapSep) => { - self.de.tokens.next(); - self.len -= 1; - Ok(Some(try!(Deserialize::deserialize(self.de)))) - } - Some(&Token::MapEnd) => Ok(None), - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStreamError), - } - } - - fn visit_value(&mut self) -> Result - where V: Deserialize, - { - Ok(try!(Deserialize::deserialize(self.de))) - } - - fn end(&mut self) -> Result<(), Error> { - assert_eq!(self.len, 0); - match self.de.tokens.next() { - Some(Token::MapEnd) => Ok(()), - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStreamError), - } - } - - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -////////////////////////////////////////////////////////////////////////// - -struct TokenDeserializerVariantVisitor<'a> { - de: &'a mut TokenDeserializer, -} - -impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> { - type Error = Error; - - fn visit_variant(&mut self) -> Result - where V: de::Deserialize, - { - de::Deserialize::deserialize(self.de) - } - - fn visit_unit(&mut self) -> Result<(), Error> { - match self.de.tokens.next() { - Some(Token::EnumUnit) => { - de::Deserialize::deserialize(self.de) - } - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStreamError), - } - } - - fn visit_newtype(&mut self) -> Result - where T: de::Deserialize, - { - match self.de.tokens.next() { - Some(Token::EnumNewtype) => { - de::Deserialize::deserialize(self.de) - } - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStreamError), - } - } - - fn visit_tuple(&mut self, - _len: usize, - visitor: V) -> Result - where V: de::Visitor, - { - match self.de.tokens.next() { - Some(Token::EnumSeq) => { - de::Deserializer::visit(self.de, visitor) - } - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStreamError), - } - } - - fn visit_struct(&mut self, - _fields: &'static [&'static str], - visitor: V) -> Result - where V: de::Visitor, - { - match self.de.tokens.next() { - Some(Token::EnumMap) => { - de::Deserializer::visit(self.de, visitor) - } - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStreamError), - } - } -} +use token::{Token, assert_de_tokens}; ////////////////////////////////////////////////////////////////////////// @@ -405,66 +29,12 @@ enum Enum { ////////////////////////////////////////////////////////////////////////// -macro_rules! btreeset { - () => { - BTreeSet::new() - }; - ($($value:expr),+) => { - { - let mut set = BTreeSet::new(); - $(set.insert($value);)+ - set - } - } -} - -macro_rules! btreemap { - () => { - BTreeMap::new() - }; - ($($key:expr => $value:expr),+) => { - { - let mut map = BTreeMap::new(); - $(map.insert($key, $value);)+ - map - } - } -} - -macro_rules! hashset { - () => { - HashSet::new() - }; - ($($value:expr),+) => { - { - let mut set = HashSet::new(); - $(set.insert($value);)+ - set - } - } -} - -macro_rules! hashmap { - () => { - HashMap::new() - }; - ($($key:expr => $value:expr),+) => { - { - let mut map = HashMap::new(); - $(map.insert($key, $value);)+ - map - } - } -} - macro_rules! declare_test { ($name:ident { $($value:expr => $tokens:expr,)+ }) => { #[test] fn $name() { $( - let mut de = TokenDeserializer::new($tokens); - let value: Result<_, Error> = Deserialize::deserialize(&mut de); - assert_eq!(value, Ok($value)); + assert_de_tokens(&$value, $tokens); )+ } } @@ -539,47 +109,47 @@ declare_tests! { test_result { Ok::(0) => vec![ Token::EnumStart("Result"), - Token::Str("Ok"), - - Token::EnumNewtype, - Token::I32(0), - Token::SeqEnd, + Token::Str("Ok"), + Token::I32(0), ], Err::(1) => vec![ Token::EnumStart("Result"), - Token::Str("Err"), - - Token::EnumNewtype, - Token::I32(1), - Token::SeqEnd, + Token::Str("Err"), + Token::I32(1), ], } test_unit { () => vec![Token::Unit], () => vec![ - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, ], () => vec![ - Token::Name("Anything"), - Token::SeqStart(0), + Token::SeqStart(None), + Token::SeqEnd, + ], + () => vec![ + Token::TupleStructStart("Anything", Some(0)), Token::SeqEnd, ], } test_unit_struct { UnitStruct => vec![Token::Unit], UnitStruct => vec![ - Token::Name("UnitStruct"), - Token::Unit, + Token::UnitStruct("UnitStruct"), ], UnitStruct => vec![ - Token::SeqStart(0), + Token::SeqStart(Some(0)), + Token::SeqEnd, + ], + UnitStruct => vec![ + Token::SeqStart(None), Token::SeqEnd, ], } test_tuple_struct { TupleStruct(1, 2, 3) => vec![ - Token::SeqStart(3), + Token::SeqStart(Some(3)), Token::SeqSep, Token::I32(1), @@ -591,8 +161,31 @@ declare_tests! { Token::SeqEnd, ], TupleStruct(1, 2, 3) => vec![ - Token::Name("TupleStruct"), - Token::SeqStart(3), + Token::SeqStart(None), + Token::SeqSep, + Token::I32(1), + + Token::SeqSep, + Token::I32(2), + + Token::SeqSep, + Token::I32(3), + Token::SeqEnd, + ], + TupleStruct(1, 2, 3) => vec![ + Token::TupleStructStart("TupleStruct", Some(3)), + Token::SeqSep, + Token::I32(1), + + Token::SeqSep, + Token::I32(2), + + Token::SeqSep, + Token::I32(3), + Token::SeqEnd, + ], + TupleStruct(1, 2, 3) => vec![ + Token::TupleStructStart("TupleStruct", None), Token::SeqSep, Token::I32(1), @@ -609,23 +202,23 @@ declare_tests! { Token::Unit, ], BTreeSet::::new() => vec![ - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, ], btreeset![btreeset![], btreeset![1], btreeset![2, 3]] => vec![ - Token::SeqStart(3), + Token::SeqStart(Some(3)), Token::SeqSep, - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, Token::SeqSep, - Token::SeqStart(1), + Token::SeqStart(Some(1)), Token::SeqSep, Token::I32(1), Token::SeqEnd, Token::SeqSep, - Token::SeqStart(2), + Token::SeqStart(Some(2)), Token::SeqSep, Token::I32(2), @@ -635,12 +228,10 @@ declare_tests! { Token::SeqEnd, ], BTreeSet::::new() => vec![ - Token::Name("Anything"), - Token::Unit, + Token::UnitStruct("Anything"), ], BTreeSet::::new() => vec![ - Token::Name("Anything"), - Token::SeqStart(0), + Token::TupleStructStart("Anything", Some(0)), Token::SeqEnd, ], } @@ -649,11 +240,11 @@ declare_tests! { Token::Unit, ], HashSet::::new() => vec![ - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, ], hashset![1, 2, 3] => vec![ - Token::SeqStart(3), + Token::SeqStart(Some(3)), Token::SeqSep, Token::I32(1), @@ -665,12 +256,10 @@ declare_tests! { Token::SeqEnd, ], HashSet::::new() => vec![ - Token::Name("Anything"), - Token::Unit, + Token::UnitStruct("Anything"), ], HashSet::::new() => vec![ - Token::Name("Anything"), - Token::SeqStart(0), + Token::TupleStructStart("Anything", Some(0)), Token::SeqEnd, ], } @@ -679,23 +268,23 @@ declare_tests! { Token::Unit, ], Vec::::new() => vec![ - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, ], vec![vec![], vec![1], vec![2, 3]] => vec![ - Token::SeqStart(3), + Token::SeqStart(Some(3)), Token::SeqSep, - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, Token::SeqSep, - Token::SeqStart(1), + Token::SeqStart(Some(1)), Token::SeqSep, Token::I32(1), Token::SeqEnd, Token::SeqSep, - Token::SeqStart(2), + Token::SeqStart(Some(2)), Token::SeqSep, Token::I32(2), @@ -705,12 +294,10 @@ declare_tests! { Token::SeqEnd, ], Vec::::new() => vec![ - Token::Name("Anything"), - Token::Unit, + Token::UnitStruct("Anything"), ], Vec::::new() => vec![ - Token::Name("Anything"), - Token::SeqStart(0), + Token::TupleStructStart("Anything", Some(0)), Token::SeqEnd, ], } @@ -719,23 +306,23 @@ declare_tests! { Token::Unit, ], [0; 0] => vec![ - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, ], ([0; 0], [1], [2, 3]) => vec![ - Token::SeqStart(3), + Token::SeqStart(Some(3)), Token::SeqSep, - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, Token::SeqSep, - Token::SeqStart(1), + Token::SeqStart(Some(1)), Token::SeqSep, Token::I32(1), Token::SeqEnd, Token::SeqSep, - Token::SeqStart(2), + Token::SeqStart(Some(2)), Token::SeqSep, Token::I32(2), @@ -745,24 +332,22 @@ declare_tests! { Token::SeqEnd, ], [0; 0] => vec![ - Token::Name("Anything"), - Token::Unit, + Token::UnitStruct("Anything"), ], [0; 0] => vec![ - Token::Name("Anything"), - Token::SeqStart(0), + Token::TupleStructStart("Anything", Some(0)), Token::SeqEnd, ], } test_tuple { (1,) => vec![ - Token::SeqStart(1), + Token::SeqStart(Some(1)), Token::SeqSep, Token::I32(1), Token::SeqEnd, ], (1, 2, 3) => vec![ - Token::SeqStart(3), + Token::SeqStart(Some(3)), Token::SeqSep, Token::I32(1), @@ -779,18 +364,18 @@ declare_tests! { Token::Unit, ], BTreeMap::::new() => vec![ - Token::MapStart(0), + Token::MapStart(Some(0)), Token::MapEnd, ], btreemap![1 => 2] => vec![ - Token::MapStart(1), + Token::MapStart(Some(1)), Token::MapSep, Token::I32(1), Token::I32(2), Token::MapEnd, ], btreemap![1 => 2, 3 => 4] => vec![ - Token::MapStart(2), + Token::MapStart(Some(2)), Token::MapSep, Token::I32(1), Token::I32(2), @@ -801,15 +386,15 @@ declare_tests! { Token::MapEnd, ], btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![ - Token::MapStart(2), + Token::MapStart(Some(2)), Token::MapSep, Token::I32(1), - Token::MapStart(0), + Token::MapStart(Some(0)), Token::MapEnd, Token::MapSep, Token::I32(2), - Token::MapStart(2), + Token::MapStart(Some(2)), Token::MapSep, Token::I32(3), Token::I32(4), @@ -821,12 +406,10 @@ declare_tests! { Token::MapEnd, ], BTreeMap::::new() => vec![ - Token::Name("Anything"), - Token::Unit, + Token::UnitStruct("Anything"), ], BTreeMap::::new() => vec![ - Token::Name("Anything"), - Token::MapStart(0), + Token::StructStart("Anything", Some(0)), Token::MapEnd, ], } @@ -835,18 +418,18 @@ declare_tests! { Token::Unit, ], HashMap::::new() => vec![ - Token::MapStart(0), + Token::MapStart(Some(0)), Token::MapEnd, ], hashmap![1 => 2] => vec![ - Token::MapStart(1), + Token::MapStart(Some(1)), Token::MapSep, Token::I32(1), Token::I32(2), Token::MapEnd, ], hashmap![1 => 2, 3 => 4] => vec![ - Token::MapStart(2), + Token::MapStart(Some(2)), Token::MapSep, Token::I32(1), Token::I32(2), @@ -857,15 +440,15 @@ declare_tests! { Token::MapEnd, ], hashmap![1 => hashmap![], 2 => hashmap![3 => 4, 5 => 6]] => vec![ - Token::MapStart(2), + Token::MapStart(Some(2)), Token::MapSep, Token::I32(1), - Token::MapStart(0), + Token::MapStart(Some(0)), Token::MapEnd, Token::MapSep, Token::I32(2), - Token::MapStart(2), + Token::MapStart(Some(2)), Token::MapSep, Token::I32(3), Token::I32(4), @@ -877,18 +460,16 @@ declare_tests! { Token::MapEnd, ], HashMap::::new() => vec![ - Token::Name("Anything"), - Token::Unit, + Token::UnitStruct("Anything"), ], HashMap::::new() => vec![ - Token::Name("Anything"), - Token::MapStart(0), + Token::StructStart("Anything", Some(0)), Token::MapEnd, ], } test_struct { Struct { a: 1, b: 2, c: 3 } => vec![ - Token::MapStart(3), + Token::MapStart(Some(3)), Token::MapSep, Token::Str("a"), Token::I32(1), @@ -903,8 +484,7 @@ declare_tests! { Token::MapEnd, ], Struct { a: 1, b: 2, c: 3 } => vec![ - Token::Name("Struct"), - Token::MapStart(3), + Token::StructStart("Struct", Some(3)), Token::MapSep, Token::Str("a"), Token::I32(1), @@ -921,83 +501,58 @@ declare_tests! { } test_enum_unit { Enum::Unit => vec![ - Token::EnumStart("Enum"), - Token::Str("Unit"), - - Token::EnumUnit, - Token::Unit, - Token::EnumEnd, + Token::EnumUnit("Enum", "Unit"), ], } test_enum_simple { Enum::Simple(1) => vec![ - Token::EnumStart("Enum"), - Token::Str("Simple"), - - Token::EnumNewtype, - Token::I32(1), - Token::EnumEnd, + Token::EnumNewtype("Enum", "Simple"), + Token::I32(1), ], } test_enum_seq { Enum::Seq(1, 2, 3) => vec![ - Token::EnumStart("Enum"), - Token::Str("Seq"), + Token::EnumSeqStart("Enum", "Seq", Some(3)), + Token::SeqSep, + Token::I32(1), - Token::EnumSeq, - Token::SeqStart(3), - Token::SeqSep, - Token::I32(1), + Token::SeqSep, + Token::I32(2), - Token::SeqSep, - Token::I32(2), - - Token::SeqSep, - Token::I32(3), - Token::SeqEnd, - Token::EnumEnd, + Token::SeqSep, + Token::I32(3), + Token::SeqEnd, ], } test_enum_map { Enum::Map { a: 1, b: 2, c: 3 } => vec![ - Token::EnumStart("Enum"), - Token::Str("Map"), + Token::EnumMapStart("Enum", "Map", Some(3)), + Token::MapSep, + Token::Str("a"), + Token::I32(1), - Token::EnumMap, - Token::MapStart(3), - Token::MapSep, - Token::Str("a"), - Token::I32(1), + Token::MapSep, + Token::Str("b"), + Token::I32(2), - Token::MapSep, - Token::Str("b"), - Token::I32(2), - - Token::MapSep, - Token::Str("c"), - Token::I32(3), - Token::MapEnd, - Token::EnumEnd, + Token::MapSep, + Token::Str("c"), + Token::I32(3), + Token::MapEnd, ], } test_enum_unit_usize { Enum::Unit => vec![ Token::EnumStart("Enum"), - Token::Usize(0), - - Token::EnumUnit, - Token::Unit, - Token::EnumEnd, + Token::Usize(0), + Token::Unit, ], } test_enum_unit_bytes { Enum::Unit => vec![ Token::EnumStart("Enum"), - Token::Bytes(b"Unit"), - - Token::EnumUnit, - Token::Unit, - Token::EnumEnd, + Token::Bytes(b"Unit"), + Token::Unit, ], } } diff --git a/serde_tests/tests/test_macros.rs b/serde_tests/tests/test_macros.rs index aa64f52e..f8396fb7 100644 --- a/serde_tests/tests/test_macros.rs +++ b/serde_tests/tests/test_macros.rs @@ -1,18 +1,4 @@ -use std::collections::BTreeMap; -use serde_json::{self, Value}; - -macro_rules! btreemap { - () => { - BTreeMap::new() - }; - ($($key:expr => $value:expr),+) => { - { - let mut map = BTreeMap::new(); - $(map.insert($key, $value);)+ - map - } - } -} +use token::{Token, assert_tokens, assert_ser_tokens, assert_de_tokens}; /* trait Trait { @@ -83,7 +69,7 @@ enum SerEnum<'a, B: 'a, C: /* Trait + */ 'a, D> where D: /* Trait + */ 'a { }, } -#[derive(Debug, PartialEq, Deserialize)] +#[derive(Debug, PartialEq, Serialize, Deserialize)] enum DeEnum /* where D: Trait */ { Unit, Seq( @@ -152,23 +138,10 @@ pub enum GenericEnum { #[test] fn test_named_unit() { - let named_unit = NamedUnit; - - assert_eq!( - serde_json::to_string(&named_unit).unwrap(), - "null".to_string() + assert_tokens( + &NamedUnit, + vec![Token::UnitStruct("NamedUnit")] ); - - assert_eq!( - serde_json::to_value(&named_unit), - Value::Null - ); - - let v: NamedUnit = serde_json::from_str("null").unwrap(); - assert_eq!(v, named_unit); - - let v: NamedUnit = serde_json::from_value(Value::Null).unwrap(); - assert_eq!(v, named_unit); } #[test] @@ -176,35 +149,41 @@ fn test_ser_named_tuple() { let a = 5; let mut b = 6; let c = 7; - let named_tuple = SerNamedTuple(&a, &mut b, c); + assert_ser_tokens( + &SerNamedTuple(&a, &mut b, c), + &[ + Token::TupleStructStart("SerNamedTuple", Some(3)), + Token::SeqSep, + Token::I32(5), - assert_eq!( - serde_json::to_string(&named_tuple).unwrap(), - "[5,6,7]" - ); + Token::SeqSep, + Token::I32(6), - assert_eq!( - serde_json::to_value(&named_tuple), - Value::Array(vec![Value::U64(5), Value::U64(6), Value::U64(7)]) + Token::SeqSep, + Token::I32(7), + + Token::SeqEnd, + ], ); } #[test] fn test_de_named_tuple() { - let v: DeNamedTuple = serde_json::from_str("[1,2,3]").unwrap(); - assert_eq!( - v, - DeNamedTuple(1, 2, 3) - ); + assert_de_tokens( + &DeNamedTuple(5, 6, 7), + vec![ + Token::TupleStructStart("DeNamedTuple", Some(3)), + Token::SeqSep, + Token::I32(5), - let v: Value = serde_json::from_str("[1,2,3]").unwrap(); - assert_eq!( - v, - Value::Array(vec![ - Value::U64(1), - Value::U64(2), - Value::U64(3), - ]) + Token::SeqSep, + Token::I32(6), + + Token::SeqSep, + Token::I32(7), + + Token::SeqEnd, + ] ); } @@ -213,60 +192,68 @@ fn test_ser_named_map() { let a = 5; let mut b = 6; let c = 7; - let named_map = SerNamedMap { - a: &a, - b: &mut b, - c: c, - }; - assert_eq!( - serde_json::to_string(&named_map).unwrap(), - "{\"a\":5,\"b\":6,\"c\":7}" - ); + assert_ser_tokens( + &SerNamedMap { + a: &a, + b: &mut b, + c: c, + }, + &[ + Token::StructStart("SerNamedMap", Some(3)), - assert_eq!( - serde_json::to_value(&named_map), - Value::Object(btreemap![ - "a".to_string() => Value::U64(5), - "b".to_string() => Value::U64(6), - "c".to_string() => Value::U64(7) - ]) + Token::MapSep, + Token::Str("a"), + Token::I32(5), + + Token::MapSep, + Token::Str("b"), + Token::I32(6), + + Token::MapSep, + Token::Str("c"), + Token::I32(7), + + Token::MapEnd, + ] ); } #[test] fn test_de_named_map() { - let v = DeNamedMap { - a: 5, - b: 6, - c: 7, - }; + assert_de_tokens( + &DeNamedMap { + a: 5, + b: 6, + c: 7, + }, + vec![ + Token::StructStart("DeNamedMap", Some(3)), - let v2: DeNamedMap = serde_json::from_str( - "{\"a\":5,\"b\":6,\"c\":7}" - ).unwrap(); - assert_eq!(v, v2); + Token::MapSep, + Token::Str("a"), + Token::I32(5), - let v2 = serde_json::from_value(Value::Object(btreemap![ - "a".to_string() => Value::U64(5), - "b".to_string() => Value::U64(6), - "c".to_string() => Value::U64(7) - ])).unwrap(); - assert_eq!(v, v2); + Token::MapSep, + Token::Str("b"), + Token::I32(6), + + Token::MapSep, + Token::Str("c"), + Token::I32(7), + + Token::MapEnd, + ] + ); } #[test] fn test_ser_enum_unit() { - assert_eq!( - serde_json::to_string(&SerEnum::Unit::).unwrap(), - "{\"Unit\":[]}" - ); - - assert_eq!( - serde_json::to_value(&SerEnum::Unit::), - Value::Object(btreemap!( - "Unit".to_string() => Value::Array(vec![])) - ) + assert_ser_tokens( + &SerEnum::Unit::, + &[ + Token::EnumUnit("SerEnum", "Unit"), + ] ); } @@ -279,37 +266,32 @@ fn test_ser_enum_seq() { let mut e = 5; //let f = 6; - assert_eq!( - serde_json::to_string(&SerEnum::Seq( + assert_ser_tokens( + &SerEnum::Seq( a, b, &c, //d, &mut e, //f, - )).unwrap(), - "{\"Seq\":[1,2,3,5]}".to_string() - ); + ), + &[ + Token::EnumSeqStart("SerEnum", "Seq", Some(4)), - assert_eq!( - serde_json::to_value(&SerEnum::Seq( - a, - b, - &c, - //d, - &mut e, - //e, - )), - Value::Object(btreemap!( - "Seq".to_string() => Value::Array(vec![ - Value::U64(1), - Value::U64(2), - Value::U64(3), - //Value::U64(4), - Value::U64(5), - //Value::U64(6), - ]) - )) + Token::SeqSep, + Token::I8(1), + + Token::SeqSep, + Token::I32(2), + + Token::SeqSep, + Token::I32(3), + + Token::SeqSep, + Token::I32(5), + + Token::SeqEnd, + ], ); } @@ -322,54 +304,46 @@ fn test_ser_enum_map() { let mut e = 5; //let f = 6; - assert_eq!( - serde_json::to_string(&SerEnum::Map { + assert_ser_tokens( + &SerEnum::Map { a: a, b: b, c: &c, //d: d, e: &mut e, //f: f, - }).unwrap(), - "{\"Map\":{\"a\":1,\"b\":2,\"c\":3,\"e\":5}}".to_string() - ); + }, + &[ + Token::EnumMapStart("SerEnum", "Map", Some(4)), - assert_eq!( - serde_json::to_value(&SerEnum::Map { - a: a, - b: b, - c: &c, - //d: d, - e: &mut e, - //f: f, - }), - Value::Object(btreemap!( - "Map".to_string() => Value::Object(btreemap![ - "a".to_string() => Value::U64(1), - "b".to_string() => Value::U64(2), - "c".to_string() => Value::U64(3), - //"d".to_string() => Value::U64(4) - "e".to_string() => Value::U64(5) - //"f".to_string() => Value::U64(6) - ]) - )) + Token::MapSep, + Token::Str("a"), + Token::I8(1), + + Token::MapSep, + Token::Str("b"), + Token::I32(2), + + Token::MapSep, + Token::Str("c"), + Token::I32(3), + + Token::MapSep, + Token::Str("e"), + Token::I32(5), + + Token::MapEnd, + ], ); } #[test] fn test_de_enum_unit() { - let v: DeEnum<_, _, _> = serde_json::from_str("{\"Unit\":[]}").unwrap(); - assert_eq!( - v, - DeEnum::Unit:: - ); - - let v: DeEnum<_, _, _> = serde_json::from_value(Value::Object(btreemap!( - "Unit".to_string() => Value::Array(vec![])) - )).unwrap(); - assert_eq!( - v, - DeEnum::Unit:: + assert_tokens( + &DeEnum::Unit::, + vec![ + Token::EnumUnit("DeEnum", "Unit"), + ], ); } @@ -382,39 +356,32 @@ fn test_de_enum_seq() { let e = 5; //let f = 6; - let v: DeEnum<_, _, _> = serde_json::from_str("{\"Seq\":[1,2,3,5]}").unwrap(); - assert_eq!( - v, - DeEnum::Seq( + assert_tokens( + &DeEnum::Seq( a, b, c, //d, e, //f, - ) - ); + ), + vec![ + Token::EnumSeqStart("DeEnum", "Seq", Some(4)), - let v: DeEnum<_, _, _> = serde_json::from_value(Value::Object(btreemap!( - "Seq".to_string() => Value::Array(vec![ - Value::U64(1), - Value::U64(2), - Value::U64(3), - //Value::U64(4), - Value::U64(5), - //Value::U64(6), - ]) - ))).unwrap(); - assert_eq!( - v, - DeEnum::Seq( - a, - b, - c, - //d, - e, - //e, - ) + Token::SeqSep, + Token::I8(1), + + Token::SeqSep, + Token::I32(2), + + Token::SeqSep, + Token::I32(3), + + Token::SeqSep, + Token::I32(5), + + Token::SeqEnd, + ], ); } @@ -427,110 +394,186 @@ fn test_de_enum_map() { let e = 5; //let f = 6; - let v: DeEnum<_, _, _> = serde_json::from_str( - "{\"Map\":{\"a\":1,\"b\":2,\"c\":3,\"e\":5}}" - ).unwrap(); - assert_eq!( - v, - DeEnum::Map { + assert_tokens( + &DeEnum::Map { a: a, b: b, c: c, //d: d, e: e, //f: f, - } - ); + }, + vec![ + Token::EnumMapStart("DeEnum", "Map", Some(4)), - let v: DeEnum<_, _, _> = serde_json::from_value(Value::Object(btreemap!( - "Map".to_string() => Value::Object(btreemap![ - "a".to_string() => Value::U64(1), - "b".to_string() => Value::U64(2), - "c".to_string() => Value::U64(3), - //"d".to_string() => Value::U64(4) - "e".to_string() => Value::U64(5) - //"f".to_string() => Value::U64(6) - ]) - ))).unwrap(); + Token::MapSep, + Token::Str("a"), + Token::I8(1), - assert_eq!( - v, - DeEnum::Map { - a: a, - b: b, - c: c, - //d: d, - e: e, - //f: f, - } + Token::MapSep, + Token::Str("b"), + Token::I32(2), + + Token::MapSep, + Token::Str("c"), + Token::I32(3), + + Token::MapSep, + Token::Str("e"), + Token::I32(5), + + Token::MapEnd, + ], ); } #[test] fn test_lifetimes() { let value = 5; - let lifetime = Lifetimes::LifetimeSeq(&value); - assert_eq!( - serde_json::to_string(&lifetime).unwrap(), - "{\"LifetimeSeq\":5}" + + assert_ser_tokens( + &Lifetimes::LifetimeSeq(&value), + &[ + Token::EnumNewtype("Lifetimes", "LifetimeSeq"), + Token::I32(5), + ] ); - let lifetime = Lifetimes::NoLifetimeSeq(5); - assert_eq!( - serde_json::to_string(&lifetime).unwrap(), - "{\"NoLifetimeSeq\":5}" + assert_ser_tokens( + &Lifetimes::NoLifetimeSeq(5), + &[ + Token::EnumNewtype("Lifetimes", "NoLifetimeSeq"), + Token::I32(5), + ] ); - let value = 5; - let lifetime = Lifetimes::LifetimeMap { a: &value }; - assert_eq!( - serde_json::to_string(&lifetime).unwrap(), - "{\"LifetimeMap\":{\"a\":5}}" + assert_ser_tokens( + &Lifetimes::LifetimeMap { a: &value }, + &[ + Token::EnumMapStart("Lifetimes", "LifetimeMap", Some(1)), + + Token::MapSep, + Token::Str("a"), + Token::I32(5), + + Token::MapEnd, + ] ); - let lifetime = Lifetimes::NoLifetimeMap { a: 5 }; - assert_eq!( - serde_json::to_string(&lifetime).unwrap(), - "{\"NoLifetimeMap\":{\"a\":5}}" + assert_ser_tokens( + &Lifetimes::NoLifetimeMap { a: 5 }, + &[ + Token::EnumMapStart("Lifetimes", "NoLifetimeMap", Some(1)), + + Token::MapSep, + Token::Str("a"), + Token::I32(5), + + Token::MapEnd, + ] ); } -macro_rules! declare_tests { - ($($name:ident { $($ty:ty : $value:expr => $str:expr,)+ })+) => { - $( - #[test] - fn $name() { - $( - let value: $ty = $value; +#[test] +fn test_generic_struct() { + assert_tokens( + &GenericStruct { x: 5u32 }, + vec![ + Token::StructStart("GenericStruct", Some(1)), - let string = serde_json::to_string(&value).unwrap(); - assert_eq!(string, $str); + Token::MapSep, + Token::Str("x"), + Token::U32(5), - let expected: $ty = serde_json::from_str(&string).unwrap(); - assert_eq!(value, expected); - )+ - } - )+ - } + Token::MapEnd, + ] + ); } -declare_tests! { - test_generic_struct { - GenericStruct : GenericStruct { x: 5 } => "{\"x\":5}", - } - test_generic_newtype_struct { - GenericNewtypeStruct : GenericNewtypeStruct(5) => "5", - } - test_generic_tuple_struct { - GenericTupleStruct : GenericTupleStruct(5, 6) => "[5,6]", - } - test_generic_enum_newtype { - GenericEnum : GenericEnum::Newtype(5) => "{\"Newtype\":5}", - } - test_generic_enum_seq { - GenericEnum : GenericEnum::Seq(5, 6) => "{\"Seq\":[5,6]}", - } - test_generic_enum_map { - GenericEnum : GenericEnum::Map { x: 5, y: 6 } => "{\"Map\":{\"x\":5,\"y\":6}}", - } +#[test] +fn test_generic_newtype_struct() { + assert_tokens( + &GenericNewtypeStruct(5u32), + vec![ + Token::StructNewtype("GenericNewtypeStruct"), + Token::U32(5), + ] + ); +} + +#[test] +fn test_generic_tuple_struct() { + assert_tokens( + &GenericTupleStruct(5u32, 6u32), + vec![ + Token::TupleStructStart("GenericTupleStruct", Some(2)), + + Token::SeqSep, + Token::U32(5), + + Token::SeqSep, + Token::U32(6), + + Token::SeqEnd, + ] + ); +} + +#[test] +fn test_generic_enum_unit() { + assert_tokens( + &GenericEnum::Unit::, + vec![ + Token::EnumUnit("GenericEnum", "Unit"), + ] + ); +} + +#[test] +fn test_generic_enum_newtype() { + assert_tokens( + &GenericEnum::Newtype::(5), + vec![ + Token::EnumNewtype("GenericEnum", "Newtype"), + Token::U32(5), + ] + ); +} + +#[test] +fn test_generic_enum_seq() { + assert_tokens( + &GenericEnum::Seq::(5, 6), + vec![ + Token::EnumSeqStart("GenericEnum", "Seq", Some(2)), + + Token::SeqSep, + Token::U32(5), + + Token::SeqSep, + Token::U32(6), + + Token::SeqEnd, + ] + ); +} + +#[test] +fn test_generic_enum_map() { + assert_tokens( + &GenericEnum::Map:: { x: 5, y: 6 }, + vec![ + Token::EnumMapStart("GenericEnum", "Map", Some(2)), + + Token::MapSep, + Token::Str("x"), + Token::U32(5), + + Token::MapSep, + Token::Str("y"), + Token::U32(6), + + Token::MapEnd, + ] + ); } diff --git a/serde_tests/tests/test_ser.rs b/serde_tests/tests/test_ser.rs index 4d56ccc1..29c22938 100644 --- a/serde_tests/tests/test_ser.rs +++ b/serde_tests/tests/test_ser.rs @@ -1,300 +1,6 @@ -use std::vec; use std::collections::BTreeMap; -use serde::ser::{Serialize, Serializer, SeqVisitor, MapVisitor}; - -#[derive(Clone, PartialEq, Debug)] -pub enum Token<'a> { - Bool(bool), - Isize(isize), - I8(i8), - I16(i16), - I32(i32), - I64(i64), - Usize(usize), - U8(u8), - U16(u16), - U32(u32), - U64(u64), - F32(f32), - F64(f64), - Char(char), - Str(&'a str), - - Option(bool), - - Unit, - UnitStruct(&'a str), - EnumUnit(&'a str, &'a str), - - EnumNewtype(&'a str, &'a str), - - SeqStart(Option), - TupleStructStart(&'a str, Option), - EnumSeqStart(&'a str, &'a str, Option), - SeqSep, - SeqEnd, - - MapStart(Option), - StructStart(&'a str, Option), - EnumMapStart(&'a str, &'a str, Option), - MapSep, - MapEnd, -} - -struct AssertSerializer<'a> { - iter: vec::IntoIter>, -} - -impl<'a> AssertSerializer<'a> { - fn new(values: Vec>) -> AssertSerializer { - AssertSerializer { - iter: values.into_iter(), - } - } - - fn visit_sequence(&mut self, mut visitor: V) -> Result<(), ()> - where V: SeqVisitor - { - while let Some(()) = try!(visitor.visit(self)) { } - - assert_eq!(self.iter.next(), Some(Token::SeqEnd)); - - Ok(()) - } - - fn visit_mapping(&mut self, mut visitor: V) -> Result<(), ()> - where V: MapVisitor - { - while let Some(()) = try!(visitor.visit(self)) { } - - assert_eq!(self.iter.next(), Some(Token::MapEnd)); - - Ok(()) - } -} - -impl<'a> Serializer for AssertSerializer<'a> { - type Error = (); - - fn visit_unit(&mut self) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::Unit)); - Ok(()) - } - - fn visit_newtype_variant(&mut self, - name: &str, - _variant_index: usize, - variant: &str, - value: T) -> Result<(), ()> - where T: Serialize, - { - assert_eq!(self.iter.next(), Some(Token::EnumNewtype(name, variant))); - value.serialize(self) - } - - fn visit_unit_struct(&mut self, name: &str) -> Result<(), ()> { - assert_eq!(self.iter.next().unwrap(), Token::UnitStruct(name)); - Ok(()) - } - - fn visit_unit_variant(&mut self, - name: &str, - _variant_index: usize, - variant: &str) -> Result<(), ()> { - assert_eq!( - self.iter.next().unwrap(), - Token::EnumUnit(name, variant) - ); - - Ok(()) - } - - fn visit_bool(&mut self, v: bool) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::Bool(v))); - Ok(()) - } - - fn visit_isize(&mut self, v: isize) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::Isize(v))); - Ok(()) - } - - fn visit_i8(&mut self, v: i8) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::I8(v))); - Ok(()) - } - - fn visit_i16(&mut self, v: i16) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::I16(v))); - Ok(()) - } - - fn visit_i32(&mut self, v: i32) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::I32(v))); - Ok(()) - } - - fn visit_i64(&mut self, v: i64) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::I64(v))); - Ok(()) - } - - fn visit_usize(&mut self, v: usize) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::Usize(v))); - Ok(()) - } - - fn visit_u8(&mut self, v: u8) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::U8(v))); - Ok(()) - } - - fn visit_u16(&mut self, v: u16) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::U16(v))); - Ok(()) - } - - fn visit_u32(&mut self, v: u32) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::U32(v))); - Ok(()) - } - - fn visit_u64(&mut self, v: u64) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::U64(v))); - Ok(()) - } - - fn visit_f32(&mut self, v: f32) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::F32(v))); - Ok(()) - } - - fn visit_f64(&mut self, v: f64) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::F64(v))); - Ok(()) - } - - fn visit_char(&mut self, v: char) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::Char(v))); - Ok(()) - } - - fn visit_str(&mut self, v: &str) -> Result<(), ()> { - assert_eq!(self.iter.next().unwrap(), Token::Str(v)); - Ok(()) - } - - fn visit_none(&mut self) -> Result<(), ()> { - assert_eq!(self.iter.next(), Some(Token::Option(false))); - Ok(()) - } - - fn visit_some(&mut self, value: V) -> Result<(), ()> - where V: Serialize, - { - assert_eq!(self.iter.next(), Some(Token::Option(true))); - value.serialize(self) - } - - - fn visit_seq(&mut self, visitor: V) -> Result<(), ()> - where V: SeqVisitor - { - let len = visitor.len(); - - assert_eq!(self.iter.next(), Some(Token::SeqStart(len))); - - self.visit_sequence(visitor) - } - - fn visit_tuple_struct(&mut self, name: &str, visitor: V) -> Result<(), ()> - where V: SeqVisitor - { - let len = visitor.len(); - - assert_eq!( - self.iter.next().unwrap(), - Token::TupleStructStart(name, len) - ); - - self.visit_sequence(visitor) - } - - fn visit_tuple_variant(&mut self, - name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<(), ()> - where V: SeqVisitor - { - let len = visitor.len(); - - assert_eq!( - self.iter.next().unwrap(), - Token::EnumSeqStart(name, variant, len) - ); - - self.visit_sequence(visitor) - } - - fn visit_seq_elt(&mut self, value: T) -> Result<(), ()> - where T: Serialize - { - assert_eq!(self.iter.next(), Some(Token::SeqSep)); - value.serialize(self) - } - - fn visit_map(&mut self, visitor: V) -> Result<(), ()> - where V: MapVisitor - { - let len = visitor.len(); - - assert_eq!(self.iter.next(), Some(Token::MapStart(len))); - - self.visit_mapping(visitor) - } - - fn visit_struct(&mut self, name: &str, visitor: V) -> Result<(), ()> - where V: MapVisitor - { - let len = visitor.len(); - - assert_eq!( - self.iter.next().unwrap(), - Token::StructStart(name, len) - ); - - self.visit_mapping(visitor) - } - - fn visit_struct_variant(&mut self, - name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<(), ()> - where V: MapVisitor - { - let len = visitor.len(); - - assert_eq!( - self.iter.next().unwrap(), - Token::EnumMapStart(name, variant, len) - ); - - self.visit_mapping(visitor) - } - - fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), ()> - where K: Serialize, - V: Serialize, - { - assert_eq!(self.iter.next(), Some(Token::MapSep)); - - try!(key.serialize(self)); - value.serialize(self) - } -} +use token::Token; ////////////////////////////////////////////////////////////////////////// @@ -321,95 +27,62 @@ enum Enum { ////////////////////////////////////////////////////////////////////////// -macro_rules! btreemap { - () => { - BTreeMap::new() - }; - ($($key:expr => $value:expr),+) => { - { - let mut map = BTreeMap::new(); - $(map.insert($key, $value);)+ - map - } - } -} - -macro_rules! declare_test { - ($name:ident { $($value:expr => $tokens:expr,)+ }) => { - #[test] - fn $name() { - $( - let mut ser = AssertSerializer::new($tokens); - assert_eq!($value.serialize(&mut ser), Ok(())); - )+ - } - } -} - -macro_rules! declare_tests { - ($($name:ident { $($value:expr => $tokens:expr,)+ })+) => { - $( - declare_test!($name { $($value => $tokens,)+ }); - )+ - } -} - -declare_tests! { +declare_ser_tests! { test_unit { - () => vec![Token::Unit], + () => &[Token::Unit], } test_bool { - true => vec![Token::Bool(true)], - false => vec![Token::Bool(false)], + true => &[Token::Bool(true)], + false => &[Token::Bool(false)], } test_isizes { - 0isize => vec![Token::Isize(0)], - 0i8 => vec![Token::I8(0)], - 0i16 => vec![Token::I16(0)], - 0i32 => vec![Token::I32(0)], - 0i64 => vec![Token::I64(0)], + 0isize => &[Token::Isize(0)], + 0i8 => &[Token::I8(0)], + 0i16 => &[Token::I16(0)], + 0i32 => &[Token::I32(0)], + 0i64 => &[Token::I64(0)], } test_usizes { - 0usize => vec![Token::Usize(0)], - 0u8 => vec![Token::U8(0)], - 0u16 => vec![Token::U16(0)], - 0u32 => vec![Token::U32(0)], - 0u64 => vec![Token::U64(0)], + 0usize => &[Token::Usize(0)], + 0u8 => &[Token::U8(0)], + 0u16 => &[Token::U16(0)], + 0u32 => &[Token::U32(0)], + 0u64 => &[Token::U64(0)], } test_floats { - 0f32 => vec![Token::F32(0.)], - 0f64 => vec![Token::F64(0.)], + 0f32 => &[Token::F32(0.)], + 0f64 => &[Token::F64(0.)], } test_char { - 'a' => vec![Token::Char('a')], + 'a' => &[Token::Char('a')], } test_str { - "abc" => vec![Token::Str("abc")], - "abc".to_string() => vec![Token::Str("abc")], + "abc" => &[Token::Str("abc")], + "abc".to_string() => &[Token::Str("abc")], } test_option { - None:: => vec![Token::Option(false)], - Some(1) => vec![ + None:: => &[Token::Option(false)], + Some(1) => &[ Token::Option(true), Token::I32(1), ], } test_result { - Ok::(0) => vec![ + Ok::(0) => &[ Token::EnumNewtype("Result", "Ok"), Token::I32(0), ], - Err::(1) => vec![ + Err::(1) => &[ Token::EnumNewtype("Result", "Err"), Token::I32(1), ], } test_slice { - &[0][..0] => vec![ + &[0][..0] => &[ Token::SeqStart(Some(0)), Token::SeqEnd, ], - &[1, 2, 3][..] => vec![ + &[1, 2, 3][..] => &[ Token::SeqStart(Some(3)), Token::SeqSep, Token::I32(1), @@ -423,11 +96,11 @@ declare_tests! { ], } test_array { - [0; 0] => vec![ + [0; 0] => &[ Token::SeqStart(Some(0)), Token::SeqEnd, ], - [1, 2, 3] => vec![ + [1, 2, 3] => &[ Token::SeqStart(Some(3)), Token::SeqSep, Token::I32(1), @@ -441,11 +114,11 @@ declare_tests! { ], } test_vec { - Vec::::new() => vec![ + Vec::::new() => &[ Token::SeqStart(Some(0)), Token::SeqEnd, ], - vec![vec![], vec![1], vec![2, 3]] => vec![ + vec![vec![], vec![1], vec![2, 3]] => &[ Token::SeqStart(Some(3)), Token::SeqSep, Token::SeqStart(Some(0)), @@ -469,13 +142,13 @@ declare_tests! { ], } test_tuple { - (1,) => vec![ + (1,) => &[ Token::SeqStart(Some(1)), Token::SeqSep, Token::I32(1), Token::SeqEnd, ], - (1, 2, 3) => vec![ + (1, 2, 3) => &[ Token::SeqStart(Some(3)), Token::SeqSep, Token::I32(1), @@ -489,14 +162,14 @@ declare_tests! { ], } test_btreemap { - btreemap![1 => 2] => vec![ + btreemap![1 => 2] => &[ Token::MapStart(Some(1)), Token::MapSep, Token::I32(1), Token::I32(2), Token::MapEnd, ], - btreemap![1 => 2, 3 => 4] => vec![ + btreemap![1 => 2, 3 => 4] => &[ Token::MapStart(Some(2)), Token::MapSep, Token::I32(1), @@ -507,7 +180,7 @@ declare_tests! { Token::I32(4), Token::MapEnd, ], - btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![ + btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => &[ Token::MapStart(Some(2)), Token::MapSep, Token::I32(1), @@ -529,10 +202,10 @@ declare_tests! { ], } test_unit_struct { - UnitStruct => vec![Token::UnitStruct("UnitStruct")], + UnitStruct => &[Token::UnitStruct("UnitStruct")], } test_tuple_struct { - TupleStruct(1, 2, 3) => vec![ + TupleStruct(1, 2, 3) => &[ Token::TupleStructStart("TupleStruct", Some(3)), Token::SeqSep, Token::I32(1), @@ -546,7 +219,7 @@ declare_tests! { ], } test_struct { - Struct { a: 1, b: 2, c: 3 } => vec![ + Struct { a: 1, b: 2, c: 3 } => &[ Token::StructStart("Struct", Some(3)), Token::MapSep, Token::Str("a"), @@ -563,9 +236,9 @@ declare_tests! { ], } test_enum { - Enum::Unit => vec![Token::EnumUnit("Enum", "Unit")], - Enum::One(42) => vec![Token::EnumNewtype("Enum", "One"), Token::I32(42)], - Enum::Seq(1, 2) => vec![ + Enum::Unit => &[Token::EnumUnit("Enum", "Unit")], + Enum::One(42) => &[Token::EnumNewtype("Enum", "One"), Token::I32(42)], + Enum::Seq(1, 2) => &[ Token::EnumSeqStart("Enum", "Seq", Some(2)), Token::SeqSep, Token::I32(1), @@ -574,7 +247,7 @@ declare_tests! { Token::I32(2), Token::SeqEnd, ], - Enum::Map { a: 1, b: 2 } => vec![ + Enum::Map { a: 1, b: 2 } => &[ Token::EnumMapStart("Enum", "Map", Some(2)), Token::MapSep, Token::Str("a"), diff --git a/serde_tests/tests/token.rs b/serde_tests/tests/token.rs new file mode 100644 index 00000000..4815dd1d --- /dev/null +++ b/serde_tests/tests/token.rs @@ -0,0 +1,789 @@ +use std::fmt; +use std::iter; + +use serde::{ser, de}; +use serde::de::value::{self, ValueDeserializer}; + +#[derive(Clone, PartialEq, Debug)] +pub enum Token<'a> { + Bool(bool), + Isize(isize), + I8(i8), + I16(i16), + I32(i32), + I64(i64), + Usize(usize), + U8(u8), + U16(u16), + U32(u32), + U64(u64), + F32(f32), + F64(f64), + Char(char), + Str(&'a str), + String(String), + Bytes(&'a [u8]), + + Option(bool), + + Unit, + UnitStruct(&'a str), + + StructNewtype(&'a str), + + EnumStart(&'a str), + EnumUnit(&'a str, &'a str), + EnumNewtype(&'a str, &'a str), + EnumSeqStart(&'a str, &'a str, Option), + EnumMapStart(&'a str, &'a str, Option), + + SeqStart(Option), + TupleStructStart(&'a str, Option), + SeqSep, + SeqEnd, + + MapStart(Option), + StructStart(&'a str, Option), + MapSep, + MapEnd, +} + +////////////////////////////////////////////////////////////////////////////// + +pub struct Serializer { + tokens: I, +} + +impl<'a, I> Serializer + where I: Iterator> +{ + pub fn new(tokens: I) -> Serializer { + Serializer { + tokens: tokens, + } + } + + fn visit_sequence(&mut self, mut visitor: V) -> Result<(), ()> + where V: ser::SeqVisitor + { + while let Some(()) = try!(visitor.visit(self)) { } + + assert_eq!(self.tokens.next(), Some(&Token::SeqEnd)); + + Ok(()) + } + + fn visit_mapping(&mut self, mut visitor: V) -> Result<(), ()> + where V: ser::MapVisitor + { + while let Some(()) = try!(visitor.visit(self)) { } + + assert_eq!(self.tokens.next(), Some(&Token::MapEnd)); + + Ok(()) + } +} + +impl<'a, I> ser::Serializer for Serializer + where I: Iterator>, +{ + type Error = (); + + fn visit_unit(&mut self) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::Unit)); + Ok(()) + } + + fn visit_newtype_variant(&mut self, + name: &str, + _variant_index: usize, + variant: &str, + value: T) -> Result<(), ()> + where T: ser::Serialize, + { + assert_eq!(self.tokens.next(), Some(&Token::EnumNewtype(name, variant))); + value.serialize(self) + } + + fn visit_unit_struct(&mut self, name: &str) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::UnitStruct(name))); + Ok(()) + } + + fn visit_unit_variant(&mut self, + name: &str, + _variant_index: usize, + variant: &str) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::EnumUnit(name, variant))); + + Ok(()) + } + + fn visit_bool(&mut self, v: bool) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::Bool(v))); + Ok(()) + } + + fn visit_isize(&mut self, v: isize) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::Isize(v))); + Ok(()) + } + + fn visit_i8(&mut self, v: i8) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::I8(v))); + Ok(()) + } + + fn visit_i16(&mut self, v: i16) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::I16(v))); + Ok(()) + } + + fn visit_i32(&mut self, v: i32) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::I32(v))); + Ok(()) + } + + fn visit_i64(&mut self, v: i64) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::I64(v))); + Ok(()) + } + + fn visit_usize(&mut self, v: usize) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::Usize(v))); + Ok(()) + } + + fn visit_u8(&mut self, v: u8) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::U8(v))); + Ok(()) + } + + fn visit_u16(&mut self, v: u16) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::U16(v))); + Ok(()) + } + + fn visit_u32(&mut self, v: u32) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::U32(v))); + Ok(()) + } + + fn visit_u64(&mut self, v: u64) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::U64(v))); + Ok(()) + } + + fn visit_f32(&mut self, v: f32) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::F32(v))); + Ok(()) + } + + fn visit_f64(&mut self, v: f64) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::F64(v))); + Ok(()) + } + + fn visit_char(&mut self, v: char) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::Char(v))); + Ok(()) + } + + fn visit_str(&mut self, v: &str) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::Str(v))); + Ok(()) + } + + fn visit_none(&mut self) -> Result<(), ()> { + assert_eq!(self.tokens.next(), Some(&Token::Option(false))); + Ok(()) + } + + fn visit_some(&mut self, value: V) -> Result<(), ()> + where V: ser::Serialize, + { + assert_eq!(self.tokens.next(), Some(&Token::Option(true))); + value.serialize(self) + } + + + fn visit_seq(&mut self, visitor: V) -> Result<(), ()> + where V: ser::SeqVisitor + { + let len = visitor.len(); + + assert_eq!(self.tokens.next(), Some(&Token::SeqStart(len))); + + self.visit_sequence(visitor) + } + + fn visit_newtype_struct(&mut self, + name: &'static str, + value: T) -> Result<(), ()> + where T: ser::Serialize, + { + assert_eq!(self.tokens.next(), Some(&Token::StructNewtype(name))); + value.serialize(self) + } + + fn visit_tuple_struct(&mut self, name: &str, visitor: V) -> Result<(), ()> + where V: ser::SeqVisitor + { + let len = visitor.len(); + + assert_eq!(self.tokens.next(), Some(&Token::TupleStructStart(name, len))); + + self.visit_sequence(visitor) + } + + fn visit_tuple_variant(&mut self, + name: &str, + _variant_index: usize, + variant: &str, + visitor: V) -> Result<(), ()> + where V: ser::SeqVisitor + { + let len = visitor.len(); + + assert_eq!(self.tokens.next(), Some(&Token::EnumSeqStart(name, variant, len))); + + self.visit_sequence(visitor) + } + + fn visit_seq_elt(&mut self, value: T) -> Result<(), ()> + where T: ser::Serialize + { + assert_eq!(self.tokens.next(), Some(&Token::SeqSep)); + value.serialize(self) + } + + fn visit_map(&mut self, visitor: V) -> Result<(), ()> + where V: ser::MapVisitor + { + let len = visitor.len(); + + assert_eq!(self.tokens.next(), Some(&Token::MapStart(len))); + + self.visit_mapping(visitor) + } + + fn visit_struct(&mut self, name: &str, visitor: V) -> Result<(), ()> + where V: ser::MapVisitor + { + let len = visitor.len(); + + assert_eq!(self.tokens.next(), Some(&Token::StructStart(name, len))); + + self.visit_mapping(visitor) + } + + fn visit_struct_variant(&mut self, + name: &str, + _variant_index: usize, + variant: &str, + visitor: V) -> Result<(), ()> + where V: ser::MapVisitor + { + let len = visitor.len(); + + assert_eq!(self.tokens.next(), Some(&Token::EnumMapStart(name, variant, len))); + + self.visit_mapping(visitor) + } + + fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), ()> + where K: ser::Serialize, + V: ser::Serialize, + { + assert_eq!(self.tokens.next(), Some(&Token::MapSep)); + + try!(key.serialize(self)); + value.serialize(self) + } + + fn format() -> &'static str { + "token" + } +} + +////////////////////////////////////////////////////////////////////////////// + +#[derive(Clone, PartialEq, Debug)] +enum Error { + SyntaxError, + EndOfStreamError, + UnknownFieldError(String), + MissingFieldError(&'static str), + InvalidName(&'static str), + UnexpectedToken(Token<'static>), + ValueError(value::Error), +} + +impl de::Error for Error { + fn syntax(_: &str) -> Error { Error::SyntaxError } + + fn end_of_stream() -> Error { Error::EndOfStreamError } + + fn unknown_field(field: &str) -> Error { + Error::UnknownFieldError(field.to_string()) + } + + fn missing_field(field: &'static str) -> Error { + Error::MissingFieldError(field) + } +} + +impl From for Error { + fn from(error: value::Error) -> Error { + Error::ValueError(error) + } +} + +struct Deserializer where I: Iterator> { + tokens: iter::Peekable, +} + +impl Deserializer + where I: Iterator> +{ + fn new(tokens: I) -> Deserializer { + Deserializer { + tokens: tokens.peekable(), + } + } + + fn visit_seq(&mut self, len: Option, mut visitor: V) -> Result + where V: de::Visitor, + { + visitor.visit_seq(DeserializerSeqVisitor { + de: self, + len: len, + }) + } + + fn visit_map(&mut self, len: Option, mut visitor: V) -> Result + where V: de::Visitor, + { + visitor.visit_map(DeserializerMapVisitor { + de: self, + len: len, + }) + } +} + +impl de::Deserializer for Deserializer + where I: Iterator> +{ + type Error = Error; + + fn visit(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + println!("visit {:?}", self.tokens.peek()); + match self.tokens.next() { + Some(Token::Bool(v)) => visitor.visit_bool(v), + Some(Token::Isize(v)) => visitor.visit_isize(v), + Some(Token::I8(v)) => visitor.visit_i8(v), + Some(Token::I16(v)) => visitor.visit_i16(v), + Some(Token::I32(v)) => visitor.visit_i32(v), + Some(Token::I64(v)) => visitor.visit_i64(v), + Some(Token::Usize(v)) => visitor.visit_usize(v), + Some(Token::U8(v)) => visitor.visit_u8(v), + Some(Token::U16(v)) => visitor.visit_u16(v), + Some(Token::U32(v)) => visitor.visit_u32(v), + Some(Token::U64(v)) => visitor.visit_u64(v), + Some(Token::F32(v)) => visitor.visit_f32(v), + Some(Token::F64(v)) => visitor.visit_f64(v), + Some(Token::Char(v)) => visitor.visit_char(v), + Some(Token::Str(v)) => visitor.visit_str(v), + Some(Token::String(v)) => visitor.visit_string(v), + Some(Token::Bytes(v)) => visitor.visit_bytes(v), + Some(Token::Option(false)) => visitor.visit_none(), + Some(Token::Option(true)) => visitor.visit_some(self), + Some(Token::Unit) => visitor.visit_unit(), + Some(Token::UnitStruct(name)) => visitor.visit_unit_struct(name), + Some(Token::SeqStart(len)) | Some(Token::TupleStructStart(_, len)) => { + self.visit_seq(len, visitor) + } + Some(Token::MapStart(len)) | Some(Token::StructStart(_, len)) => { + self.visit_map(len, visitor) + } + //Some(Token::Name(_)) => self.visit(visitor), + Some(token) => Err(Error::UnexpectedToken(token)), + None => Err(Error::EndOfStreamError), + } + } + + /// Hook into `Option` deserializing so we can treat `Unit` as a + /// `None`, or a regular value as `Some(value)`. + fn visit_option(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + match self.tokens.peek() { + Some(&Token::Option(false)) => { + self.tokens.next(); + visitor.visit_none() + } + Some(&Token::Option(true)) => { + self.tokens.next(); + visitor.visit_some(self) + } + Some(&Token::Unit) => { + self.tokens.next(); + visitor.visit_none() + } + Some(_) => visitor.visit_some(self), + None => Err(Error::EndOfStreamError), + } + } + + fn visit_enum(&mut self, + name: &str, + _variants: &'static [&'static str], + mut visitor: V) -> Result + where V: de::EnumVisitor, + { + match self.tokens.peek() { + Some(&Token::EnumStart(n)) if name == n => { + self.tokens.next(); + + visitor.visit(DeserializerVariantVisitor { + de: self, + }) + } + Some(&Token::EnumUnit(n, _)) + | Some(&Token::EnumNewtype(n, _)) + | Some(&Token::EnumSeqStart(n, _, _)) + | Some(&Token::EnumMapStart(n, _, _)) if name == n => { + visitor.visit(DeserializerVariantVisitor { + de: self, + }) + } + Some(_) => { + let token = self.tokens.next().unwrap(); + Err(Error::UnexpectedToken(token)) + } + None => { return Err(Error::EndOfStreamError); } + } + } + + fn visit_unit_struct(&mut self, name: &str, mut visitor: V) -> Result + where V: de::Visitor, + { + match self.tokens.peek() { + Some(&Token::UnitStruct(n)) => { + self.tokens.next(); + if name == n { + visitor.visit_unit() + } else { + Err(Error::InvalidName(n)) + } + } + Some(_) => self.visit(visitor), + None => Err(Error::EndOfStreamError), + } + } + + fn visit_newtype_struct(&mut self, + name: &str, + mut visitor: V) -> Result + where V: de::Visitor, + { + match self.tokens.peek() { + Some(&Token::StructNewtype(n)) => { + self.tokens.next(); + if name == n { + visitor.visit_newtype_struct(self) + } else { + Err(Error::InvalidName(n)) + } + } + Some(_) => self.visit(visitor), + None => Err(Error::EndOfStreamError), + } + } + + fn visit_tuple_struct(&mut self, + name: &str, + len: usize, + mut visitor: V) -> Result + where V: de::Visitor, + { + match self.tokens.peek() { + Some(&Token::UnitStruct(n)) => { + self.tokens.next(); + if name == n { + visitor.visit_unit() + } else { + Err(Error::InvalidName(n)) + } + } + Some(&Token::TupleStructStart(n, _)) => { + self.tokens.next(); + if name == n { + self.visit_seq(Some(len), visitor) + } else { + Err(Error::InvalidName(n)) + } + } + Some(&Token::SeqStart(_)) => { + self.tokens.next(); + self.visit_seq(Some(len), visitor) + } + Some(_) => self.visit(visitor), + None => Err(Error::EndOfStreamError), + } + } + + fn visit_struct(&mut self, + name: &str, + fields: &'static [&'static str], + visitor: V) -> Result + where V: de::Visitor, + { + match self.tokens.peek() { + Some(&Token::StructStart(n, _)) => { + self.tokens.next(); + if name == n { + self.visit_map(Some(fields.len()), visitor) + } else { + Err(Error::InvalidName(n)) + } + } + Some(&Token::MapStart(_)) => { + self.tokens.next(); + self.visit_map(Some(fields.len()), visitor) + } + Some(_) => self.visit(visitor), + None => Err(Error::EndOfStreamError), + } + } + + fn format() -> &'static str { + "token" + } +} + +////////////////////////////////////////////////////////////////////////// + +struct DeserializerSeqVisitor<'a, I: 'a> where I: Iterator> { + de: &'a mut Deserializer, + len: Option, +} + +impl<'a, I> de::SeqVisitor for DeserializerSeqVisitor<'a, I> + where I: Iterator>, +{ + type Error = Error; + + fn visit(&mut self) -> Result, Error> + where T: de::Deserialize, + { + match self.de.tokens.peek() { + Some(&Token::SeqSep) => { + self.de.tokens.next(); + self.len = self.len.map(|len| len - 1); + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + Some(&Token::SeqEnd) => Ok(None), + Some(_) => { + let token = self.de.tokens.next().unwrap(); + Err(Error::UnexpectedToken(token)) + } + None => Err(Error::EndOfStreamError), + } + } + + fn end(&mut self) -> Result<(), Error> { + //assert_eq!(self.len.unwrap_or(0), 0); + match self.de.tokens.next() { + Some(Token::SeqEnd) => Ok(()), + Some(token) => Err(Error::UnexpectedToken(token)), + None => Err(Error::EndOfStreamError), + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.len.unwrap_or(0); + (len, self.len) + } +} + +////////////////////////////////////////////////////////////////////////// + +struct DeserializerMapVisitor<'a, I: 'a> where I: Iterator> { + de: &'a mut Deserializer, + len: Option, +} + +impl<'a, I> de::MapVisitor for DeserializerMapVisitor<'a, I> + where I: Iterator>, +{ + type Error = Error; + + fn visit_key(&mut self) -> Result, Error> + where K: de::Deserialize, + { + match self.de.tokens.peek() { + Some(&Token::MapSep) => { + self.de.tokens.next(); + self.len = self.len.map(|len| len - 1); + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + Some(&Token::MapEnd) => Ok(None), + Some(_) => { + let token = self.de.tokens.next().unwrap(); + Err(Error::UnexpectedToken(token)) + } + None => Err(Error::EndOfStreamError), + } + } + + fn visit_value(&mut self) -> Result + where V: de::Deserialize, + { + Ok(try!(de::Deserialize::deserialize(self.de))) + } + + fn end(&mut self) -> Result<(), Error> { + //assert_eq!(self.len.unwrap_or(0), 0); + match self.de.tokens.next() { + Some(Token::MapEnd) => Ok(()), + Some(token) => Err(Error::UnexpectedToken(token)), + None => Err(Error::EndOfStreamError), + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.len.unwrap_or(0); + (len, self.len) + } +} + +////////////////////////////////////////////////////////////////////////// + +struct DeserializerVariantVisitor<'a, I: 'a> where I: Iterator> { + de: &'a mut Deserializer, +} + +impl<'a, I> de::VariantVisitor for DeserializerVariantVisitor<'a, I> + where I: Iterator>, +{ + type Error = Error; + + fn visit_variant(&mut self) -> Result + where V: de::Deserialize, + { + match self.de.tokens.peek() { + Some(&Token::EnumUnit(_, v)) + | Some(&Token::EnumNewtype(_, v)) + | Some(&Token::EnumSeqStart(_, v, _)) + | Some(&Token::EnumMapStart(_, v, _)) => { + let value = try!(de::Deserialize::deserialize(&mut v.into_deserializer())); + Ok(value) + } + Some(_) => { + de::Deserialize::deserialize(self.de) + } + None => Err(Error::EndOfStreamError), + } + } + + fn visit_unit(&mut self) -> Result<(), Error> { + match self.de.tokens.peek() { + Some(&Token::EnumUnit(_, _)) => { + self.de.tokens.next(); + Ok(()) + } + Some(_) => { + de::Deserialize::deserialize(self.de) + } + None => Err(Error::EndOfStreamError), + } + } + + fn visit_newtype(&mut self) -> Result + where T: de::Deserialize, + { + match self.de.tokens.peek() { + Some(&Token::EnumNewtype(_, _)) => { + self.de.tokens.next(); + de::Deserialize::deserialize(self.de) + } + Some(_) => { + de::Deserialize::deserialize(self.de) + } + None => Err(Error::EndOfStreamError), + } + } + + fn visit_tuple(&mut self, + len: usize, + visitor: V) -> Result + where V: de::Visitor, + { + match self.de.tokens.peek() { + Some(&Token::EnumSeqStart(_, _, Some(enum_len))) => { + let token = self.de.tokens.next().unwrap(); + + if len == enum_len { + self.de.visit_seq(Some(len), visitor) + } else { + Err(Error::UnexpectedToken(token)) + } + } + Some(_) => { + de::Deserialize::deserialize(self.de) + } + None => Err(Error::EndOfStreamError), + } + } + + fn visit_struct(&mut self, + fields: &'static [&'static str], + visitor: V) -> Result + where V: de::Visitor, + { + match self.de.tokens.peek() { + Some(&Token::EnumMapStart(_, _, Some(enum_len))) => { + let token = self.de.tokens.next().unwrap(); + + if fields.len() == enum_len { + self.de.visit_map(Some(fields.len()), visitor) + } else { + Err(Error::UnexpectedToken(token)) + } + } + Some(_) => { + de::Deserialize::deserialize(self.de) + } + None => Err(Error::EndOfStreamError), + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +pub fn assert_ser_tokens(value: &T, tokens: &[Token]) + where T: ser::Serialize, +{ + let mut ser = Serializer::new(tokens.iter()); + assert_eq!(ser::Serialize::serialize(value, &mut ser), Ok(())); + assert_eq!(ser.tokens.next(), None); +} + +pub fn assert_de_tokens(value: &T, tokens: Vec>) + where T: de::Deserialize + PartialEq + fmt::Debug, +{ + let mut de = Deserializer::new(tokens.into_iter()); + let v: Result = de::Deserialize::deserialize(&mut de); + assert_eq!(v.as_ref(), Ok(value)); + assert_eq!(de.tokens.next(), None); +} + +pub fn assert_tokens(value: &T, tokens: Vec>) + where T: ser::Serialize + de::Deserialize + PartialEq + fmt::Debug, +{ + assert_ser_tokens(value, &tokens[..]); + assert_de_tokens(value, tokens); +} From fa3460e0a73143a4ed5ea854f809558df05a852d Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sat, 29 Aug 2015 18:09:51 -0700 Subject: [PATCH 2/2] Migrate serde_json into it's own repo New location is https://github.com/serde-rs/json. --- serde_json/Cargo.toml | 14 - serde_json/src/builder.rs | 85 -- serde_json/src/de.rs | 820 ------------ serde_json/src/error.rs | 175 --- serde_json/src/lib.rs | 122 -- serde_json/src/ser.rs | 637 ---------- serde_json/src/value.rs | 951 -------------- serde_macros/Cargo.toml | 1 - serde_macros/benches/bench.rs | 1 - serde_macros/examples/json.rs | 66 - serde_tests/benches/bench.rs | 1 - serde_tests/benches/bench.rs.in | 1 - serde_tests/benches/bench_log.rs | 1606 ------------------------ serde_tests/benches/bench_map.rs | 14 +- serde_tests/benches/bench_vec.rs | 14 +- serde_tests/tests/test.rs | 1 - serde_tests/tests/test_json.rs | 1363 -------------------- serde_tests/tests/test_json_builder.rs | 50 - 18 files changed, 14 insertions(+), 5908 deletions(-) delete mode 100644 serde_json/Cargo.toml delete mode 100644 serde_json/src/builder.rs delete mode 100644 serde_json/src/de.rs delete mode 100644 serde_json/src/error.rs delete mode 100644 serde_json/src/lib.rs delete mode 100644 serde_json/src/ser.rs delete mode 100644 serde_json/src/value.rs delete mode 100644 serde_macros/examples/json.rs delete mode 100644 serde_tests/benches/bench_log.rs delete mode 100644 serde_tests/tests/test_json.rs delete mode 100644 serde_tests/tests/test_json_builder.rs 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)); -}