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); +}