Replace serde1 with serde2!

Closes #26!
This commit is contained in:
Erick Tryzelaar
2015-03-08 22:56:33 -07:00
parent 6726bd12ae
commit 805a3435cf
48 changed files with 4635 additions and 15428 deletions
-368
View File
@@ -1,368 +0,0 @@
#![feature(plugin)]
#![plugin(serde_macros)]
extern crate serde;
use std::collections::BTreeMap;
use std::{option, string};
use serde::de::{Deserializer, Deserialize, Token, TokenKind, IgnoreTokens};
macro_rules! treemap {
($($k:expr => $v:expr),*) => ({
let mut _m = ::std::collections::BTreeMap::new();
$(_m.insert($k, $v);)*
_m
})
}
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug)]
struct Inner {
a: (),
b: usize,
c: BTreeMap<string::String, option::Option<char>>,
}
impl<
D: Deserializer<E>,
E
> Deserialize<D, E> for Inner {
#[inline]
fn deserialize_token(d: &mut D, token: Token) -> Result<Inner, E> {
try!(d.expect_struct_start(token, "Inner"));
let mut a = None;
let mut b = None;
let mut c = None;
static FIELDS: &'static [&'static str] = &["a", "b", "c"];
loop {
let idx = match try!(d.expect_struct_field_or_end(FIELDS)) {
Some(idx) => idx,
None => { break; }
};
match idx {
Some(0) => { a = Some(try!(d.expect_struct_value())); }
Some(1) => { b = Some(try!(d.expect_struct_value())); }
Some(2) => { c = Some(try!(d.expect_struct_value())); }
Some(_) => unreachable!(),
None => { let _: IgnoreTokens = try!(Deserialize::deserialize(d)); }
}
}
Ok(Inner { a: a.unwrap(), b: b.unwrap(), c: c.unwrap() })
}
}
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug)]
struct Outer {
inner: Vec<Inner>,
}
impl<D: Deserializer<E>, E> Deserialize<D, E> for Outer {
#[inline]
fn deserialize_token(d: &mut D, token: Token) -> Result<Outer, E> {
try!(d.expect_struct_start(token, "Outer"));
static FIELDS: &'static [&'static str] = &["inner"];
let mut inner = None;
loop {
let idx = match try!(d.expect_struct_field_or_end(FIELDS)) {
Some(idx) => idx,
None => { break; }
};
match idx {
Some(0) => { inner = Some(try!(d.expect_struct_value())); }
Some(_) => unreachable!(),
None => { let _: IgnoreTokens = try!(Deserialize::deserialize(d)); }
}
}
Ok(Outer { inner: inner.unwrap() })
}
}
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug)]
enum Animal {
Dog,
Frog(string::String, isize)
}
impl<D: Deserializer<E>, E> Deserialize<D, E> for Animal {
#[inline]
fn deserialize_token(d: &mut D, token: Token) -> Result<Animal, E> {
match try!(d.expect_enum_start(token, "Animal", &["Dog", "Frog"])) {
0 => {
try!(d.expect_enum_end());
Ok(Animal::Dog)
}
1 => {
let x0 = try!(Deserialize::deserialize(d));
let x1 = try!(Deserialize::deserialize(d));
try!(d.expect_enum_end());
Ok(Animal::Frog(x0, x1))
}
_ => unreachable!(),
}
}
}
//////////////////////////////////////////////////////////////////////////////
#[derive(Debug)]
enum Error {
EndOfStream,
SyntaxError(Vec<TokenKind>),
UnexpectedName,
ConversionError,
MissingField(&'static str),
}
//////////////////////////////////////////////////////////////////////////////
struct TokenDeserializer<Iter> {
tokens: Iter,
}
impl<Iter: Iterator<Item=Token>> TokenDeserializer<Iter> {
#[inline]
fn new(tokens: Iter) -> TokenDeserializer<Iter> {
TokenDeserializer {
tokens: tokens,
}
}
}
impl<Iter: Iterator<Item=Token>> Iterator for TokenDeserializer<Iter> {
type Item = Result<Token, Error>;
#[inline]
fn next(&mut self) -> option::Option<Result<Token, Error>> {
self.tokens.next().map(|token| Ok(token))
}
}
impl<Iter: Iterator<Item=Token>> Deserializer<Error> for TokenDeserializer<Iter> {
fn end_of_stream_error(&mut self) -> Error {
Error::EndOfStream
}
fn syntax_error(&mut self, _token: Token, expected: &[TokenKind]) -> Error {
Error::SyntaxError(expected.to_vec())
}
fn unexpected_name_error(&mut self, _token: Token) -> Error {
Error::UnexpectedName
}
fn conversion_error(&mut self, _token: Token) -> Error {
Error::ConversionError
}
#[inline]
fn missing_field<
T: Deserialize<TokenDeserializer<Iter>, Error>
>(&mut self, field: &'static str) -> Result<T, Error> {
Err(Error::MissingField(field))
}
}
//////////////////////////////////////////////////////////////////////////////
macro_rules! test_value {
($name:ident, [$($tokens:expr => $value:expr, $ty:ty),*]) => {
#[test]
fn $name() {
$(
let mut deserializer = TokenDeserializer::new($tokens.into_iter());
let value: $ty = Deserialize::deserialize(&mut deserializer).unwrap();
assert_eq!(value, $value);
)+
}
}
}
test_value!(test_primitives, [
vec!(Token::Null) => (), (),
vec!(Token::Bool(true)) => true, bool,
vec!(Token::Bool(false)) => false, bool,
vec!(Token::Isize(5)) => 5, isize,
vec!(Token::I8(5)) => 5, i8,
vec!(Token::I16(5)) => 5, i16,
vec!(Token::I32(5)) => 5, i32,
vec!(Token::I64(5)) => 5, i64,
vec!(Token::Usize(5)) => 5, usize,
vec!(Token::U8(5)) => 5, u8,
vec!(Token::U16(5)) => 5, u16,
vec!(Token::U32(5)) => 5, u32,
vec!(Token::U64(5)) => 5, u64,
vec!(Token::F32(5.0)) => 5.0, f32,
vec!(Token::F64(5.0)) => 5.0, f64,
vec!(Token::Char('c')) => 'c', char,
vec!(Token::Str("abc")) => "abc", &str,
vec!(Token::String("abc".to_string())) => "abc".to_string(), string::String
]);
test_value!(test_tuples, [
vec!(
Token::TupleStart(0),
Token::End,
) => (), (),
vec!(
Token::TupleStart(2),
Token::Isize(5),
Token::Str("a"),
Token::End,
) => (5, "a"), (isize, &'static str),
vec!(
Token::TupleStart(3),
Token::Null,
Token::TupleStart(0),
Token::End,
Token::TupleStart(2),
Token::Isize(5),
Token::Str("a"),
Token::End,
Token::End,
) => ((), (), (5, "a")), ((), (), (isize, &'static str))
]);
test_value!(test_options, [
vec!(Token::Option(false)) => None, option::Option<isize>,
vec!(
Token::Option(true),
Token::Isize(5),
) => Some(5), option::Option<isize>
]);
test_value!(test_structs, [
vec!(
Token::StructStart("Outer", 1),
Token::Str("inner"),
Token::SeqStart(0),
Token::End,
Token::End,
) => Outer { inner: vec!() }, Outer,
vec!(
Token::StructStart("Outer", 1),
Token::Str("inner"),
Token::SeqStart(1),
Token::StructStart("Inner", 3),
Token::Str("a"),
Token::Null,
Token::Str("b"),
Token::Usize(5),
Token::Str("c"),
Token::MapStart(1),
Token::String("abc".to_string()),
Token::Option(true),
Token::Char('c'),
Token::End,
Token::End,
Token::End,
Token::End,
) => Outer {
inner: vec!(
Inner {
a: (),
b: 5,
c: treemap!("abc".to_string() => Some('c')),
},
),
}, Outer
]);
test_value!(test_enums, [
vec!(
Token::EnumStart("Animal", "Dog", 0),
Token::End,
) => Animal::Dog, Animal,
vec!(
Token::EnumStart("Animal", "Frog", 2),
Token::String("Henry".to_string()),
Token::Isize(349),
Token::End,
) => Animal::Frog("Henry".to_string(), 349), Animal
]);
test_value!(test_vecs, [
vec!(
Token::SeqStart(0),
Token::End,
) => vec!(), Vec<isize>,
vec!(
Token::SeqStart(3),
Token::Isize(5),
Token::Isize(6),
Token::Isize(7),
Token::End,
) => vec!(5, 6, 7), Vec<isize>,
vec!(
Token::SeqStart(3),
Token::SeqStart(1),
Token::Isize(1),
Token::End,
Token::SeqStart(2),
Token::Isize(2),
Token::Isize(3),
Token::End,
Token::SeqStart(3),
Token::Isize(4),
Token::Isize(5),
Token::Isize(6),
Token::End,
Token::End,
) => vec!(vec!(1), vec!(2, 3), vec!(4, 5, 6)), Vec<Vec<isize>>
]);
test_value!(test_treemaps, [
vec!(
Token::MapStart(0),
Token::End,
) => treemap!(), BTreeMap<isize, string::String>,
vec!(
Token::MapStart(2),
Token::Isize(5),
Token::String("a".to_string()),
Token::Isize(6),
Token::String("b".to_string()),
Token::End,
) => treemap!(5is => "a".to_string(), 6is => "b".to_string()), BTreeMap<isize, string::
String>
]);
-1384
View File
File diff suppressed because it is too large Load Diff
-30
View File
@@ -1,30 +0,0 @@
#![feature(plugin)]
#![plugin(serde_macros)]
extern crate serde;
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
struct Test {
#[serial_name = "$schema"]
schema: String,
title: String,
#[serial_name = "type"]
ty: isize
}
#[test]
fn test_json_struct() {
let input = Test {
schema: "a".to_string(),
title: "b".to_string(),
ty: 3,
};
let s = serde::json::to_string(&input).unwrap();
assert_eq!(&s[], r#"{"$schema":"a","title":"b","type":3}"#);
let output: Test = serde::json::from_str(&s).unwrap();
assert_eq!(input, output);
}
-517
View File
@@ -1,517 +0,0 @@
#![feature(plugin)]
#![plugin(serde_macros)]
extern crate serde;
use std::collections::{HashMap, BTreeMap};
use std::{option, string};
use serde::ser::{Serializer, Serialize};
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug)]
#[derive_serialize]
struct Inner {
a: (),
b: usize,
c: HashMap<string::String, option::Option<char>>,
}
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug)]
#[derive_serialize]
struct Outer {
inner: Vec<Inner>,
}
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug)]
#[derive_serialize]
enum Animal {
Dog,
Frog(String, isize)
}
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug)]
pub enum Token<'a> {
Null,
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),
TupleStart(usize),
TupleSep,
TupleEnd,
StructStart(&'a str, usize),
StructSep(&'a str),
StructEnd,
EnumStart(&'a str, &'a str, usize),
EnumSep,
EnumEnd,
Option(bool),
SeqStart(usize),
SeqEnd,
MapStart(usize),
MapEnd,
}
#[derive(Debug)]
#[allow(dead_code)]
enum Error {
EndOfStream,
SyntaxError,
}
//////////////////////////////////////////////////////////////////////////////
struct AssertSerializer<Iter> {
iter: Iter,
}
impl<'a, Iter: Iterator<Item=Token<'a>>> AssertSerializer<Iter> {
fn new(iter: Iter) -> AssertSerializer<Iter> {
AssertSerializer {
iter: iter,
}
}
fn serialize<'b>(&mut self, token: Token<'b>) -> Result<(), Error> {
let t = match self.iter.next() {
Some(t) => t,
None => { panic!(); }
};
assert_eq!(t, token);
Ok(())
}
}
impl<'a, Iter: Iterator<Item=Token<'a>>> Serializer<Error> for AssertSerializer<Iter> {
fn serialize_null(&mut self) -> Result<(), Error> {
self.serialize(Token::Null)
}
fn serialize_bool(&mut self, v: bool) -> Result<(), Error> {
self.serialize(Token::Bool(v))
}
fn serialize_isize(&mut self, v: isize) -> Result<(), Error> {
self.serialize(Token::Isize(v))
}
fn serialize_i8(&mut self, v: i8) -> Result<(), Error> {
self.serialize(Token::I8(v))
}
fn serialize_i16(&mut self, v: i16) -> Result<(), Error> {
self.serialize(Token::I16(v))
}
fn serialize_i32(&mut self, v: i32) -> Result<(), Error> {
self.serialize(Token::I32(v))
}
fn serialize_i64(&mut self, v: i64) -> Result<(), Error> {
self.serialize(Token::I64(v))
}
fn serialize_usize(&mut self, v: usize) -> Result<(), Error> {
self.serialize(Token::Usize(v))
}
fn serialize_u8(&mut self, v: u8) -> Result<(), Error> {
self.serialize(Token::U8(v))
}
fn serialize_u16(&mut self, v: u16) -> Result<(), Error> {
self.serialize(Token::U16(v))
}
fn serialize_u32(&mut self, v: u32) -> Result<(), Error> {
self.serialize(Token::U32(v))
}
fn serialize_u64(&mut self, v: u64) -> Result<(), Error> {
self.serialize(Token::U64(v))
}
fn serialize_f32(&mut self, v: f32) -> Result<(), Error> {
self.serialize(Token::F32(v))
}
fn serialize_f64(&mut self, v: f64) -> Result<(), Error> {
self.serialize(Token::F64(v))
}
fn serialize_char(&mut self, v: char) -> Result<(), Error> {
self.serialize(Token::Char(v))
}
fn serialize_str(&mut self, v: &str) -> Result<(), Error> {
self.serialize(Token::Str(v))
}
fn serialize_tuple_start(&mut self, len: usize) -> Result<(), Error> {
self.serialize(Token::TupleStart(len))
}
fn serialize_tuple_elt<
T: Serialize<AssertSerializer<Iter>, Error>
>(&mut self, value: &T) -> Result<(), Error> {
try!(self.serialize(Token::TupleSep));
value.serialize(self)
}
fn serialize_tuple_end(&mut self) -> Result<(), Error> {
self.serialize(Token::TupleEnd)
}
fn serialize_struct_start(&mut self, name: &str, len: usize) -> Result<(), Error> {
self.serialize(Token::StructStart(name, len))
}
fn serialize_struct_elt<
T: Serialize<AssertSerializer<Iter>, Error>
>(&mut self, name: &str, value: &T) -> Result<(), Error> {
try!(self.serialize(Token::StructSep(name)));
value.serialize(self)
}
fn serialize_struct_end(&mut self) -> Result<(), Error> {
self.serialize(Token::StructEnd)
}
fn serialize_enum_start(&mut self, name: &str, variant: &str, len: usize) -> Result<(), Error> {
self.serialize(Token::EnumStart(name, variant, len))
}
fn serialize_enum_elt<
T: Serialize<AssertSerializer<Iter>, Error>
>(&mut self, value: &T) -> Result<(), Error> {
try!(self.serialize(Token::EnumSep));
value.serialize(self)
}
fn serialize_enum_end(&mut self) -> Result<(), Error> {
self.serialize(Token::EnumEnd)
}
fn serialize_option<
T: Serialize<AssertSerializer<Iter>, Error>
>(&mut self, v: &option::Option<T>) -> Result<(), Error> {
match *v {
Some(ref v) => {
try!(self.serialize(Token::Option(true)));
v.serialize(self)
}
None => {
self.serialize(Token::Option(false))
}
}
}
fn serialize_seq<
T: Serialize<AssertSerializer<Iter>, Error>,
SeqIter: Iterator<Item=T>
>(&mut self, iter: SeqIter) -> Result<(), Error> {
let (len, _) = iter.size_hint();
try!(self.serialize(Token::SeqStart(len)));
for elt in iter {
try!(elt.serialize(self));
}
self.serialize(Token::SeqEnd)
}
fn serialize_map<
K: Serialize<AssertSerializer<Iter>, Error>,
V: Serialize<AssertSerializer<Iter>, Error>,
MapIter: Iterator<Item=(K, V)>
>(&mut self, iter: MapIter) -> Result<(), Error> {
let (len, _) = iter.size_hint();
try!(self.serialize(Token::MapStart(len)));
for (key, value) in iter {
try!(key.serialize(self));
try!(value.serialize(self));
}
self.serialize(Token::MapEnd)
}
}
//////////////////////////////////////////////////////////////////////////////
#[test]
fn test_tokens_int() {
let tokens = vec!(
Token::Isize(5)
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
5is.serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_str() {
let tokens = vec!(
Token::Str("a"),
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
"a".serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_null() {
let tokens = vec!(
Token::Null,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
().serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_option_none() {
let tokens = vec!(
Token::Option(false),
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
None::<isize>.serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_option_some() {
let tokens = vec!(
Token::Option(true),
Token::Isize(5),
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
Some(5is).serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_tuple() {
let tokens = vec!(
Token::TupleStart(2),
Token::TupleSep,
Token::Isize(5),
Token::TupleSep,
Token::Str("a"),
Token::TupleEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
(5is, "a").serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_tuple_compound() {
let tokens = vec!(
Token::TupleStart(3),
Token::TupleSep,
Token::Null,
Token::TupleSep,
Token::Null,
Token::TupleSep,
Token::TupleStart(2),
Token::TupleSep,
Token::Isize(5),
Token::TupleSep,
Token::Str("a"),
Token::TupleEnd,
Token::TupleEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
((), (), (5is, "a")).serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_struct_empty() {
let tokens = vec!(
Token::StructStart("Outer", 1),
Token::StructSep("inner"),
Token::SeqStart(0),
Token::SeqEnd,
Token::StructEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
Outer { inner: vec!() }.serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_struct() {
let tokens = vec!(
Token::StructStart("Outer", 1),
Token::StructSep("inner"),
Token::SeqStart(1),
Token::StructStart("Inner", 3),
Token::StructSep("a"),
Token::Null,
Token::StructSep("b"),
Token::Usize(5),
Token::StructSep("c"),
Token::MapStart(1),
Token::Str("abc"),
Token::Option(true),
Token::Char('c'),
Token::MapEnd,
Token::StructEnd,
Token::SeqEnd,
Token::StructEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
let mut map = HashMap::new();
map.insert("abc".to_string(), Some('c'));
Outer {
inner: vec!(
Inner {
a: (),
b: 5,
c: map,
},
)
}.serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_enum() {
let tokens = vec!(
Token::EnumStart("Animal", "Dog", 0),
Token::EnumEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
Animal::Dog.serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
let tokens = vec!(
Token::EnumStart("Animal", "Frog", 2),
Token::EnumSep,
Token::Str("Henry"),
Token::EnumSep,
Token::Isize(349),
Token::EnumEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
Animal::Frog("Henry".to_string(), 349).serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_vec_empty() {
let tokens = vec!(
Token::SeqStart(0),
Token::SeqEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
let v: Vec<isize> = vec!();
v.serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_vec() {
let tokens = vec!(
Token::SeqStart(3),
Token::Isize(5),
Token::Isize(6),
Token::Isize(7),
Token::SeqEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
(vec!(5is, 6, 7)).serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_vec_compound() {
let tokens = vec!(
Token::SeqStart(3),
Token::SeqStart(1),
Token::Isize(1),
Token::SeqEnd,
Token::SeqStart(2),
Token::Isize(2),
Token::Isize(3),
Token::SeqEnd,
Token::SeqStart(3),
Token::Isize(4),
Token::Isize(5),
Token::Isize(6),
Token::SeqEnd,
Token::SeqEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
(vec!(vec!(1is), vec!(2, 3), vec!(4, 5, 6))).serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
#[test]
fn test_tokens_treemap() {
let tokens = vec!(
Token::MapStart(2),
Token::Isize(5),
Token::Str("a"),
Token::Isize(6),
Token::Str("b"),
Token::MapEnd,
);
let mut serializer = AssertSerializer::new(tokens.into_iter());
let mut map = BTreeMap::new();
map.insert(5is, "a".to_string());
map.insert(6is, "b".to_string());
map.serialize(&mut serializer).unwrap();
assert_eq!(serializer.iter.next(), None);
}
+651
View File
@@ -0,0 +1,651 @@
#![feature(custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate test;
extern crate serde;
use std::collections::BTreeMap;
use std::iter;
use std::vec;
use serde::de::{self, Deserialize, Deserializer, Visitor};
#[derive(Debug)]
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),
Option(bool),
Unit,
NamedUnit(&'a str),
SeqStart(usize),
NamedSeqStart(&'a str, usize),
SeqSep(bool),
SeqEnd,
MapStart(usize),
NamedMapStart(&'a str, usize),
MapSep(bool),
MapEnd,
EnumStart(&'a str, &'a str),
EnumEnd,
}
struct TokenDeserializer<'a> {
tokens: iter::Peekable<vec::IntoIter<Token<'a>>>,
}
impl<'a> TokenDeserializer<'a> {
fn new(tokens: Vec<Token<'a>>) -> TokenDeserializer<'a> {
TokenDeserializer {
tokens: tokens.into_iter().peekable(),
}
}
}
#[derive(Copy, PartialEq, Debug)]
enum Error {
SyntaxError,
EndOfStreamError,
MissingFieldError(&'static str),
}
impl de::Error for Error {
fn syntax_error() -> Error { Error::SyntaxError }
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
fn missing_field_error(field: &'static str) -> Error {
Error::MissingFieldError(field)
}
}
impl<'a> Deserializer for TokenDeserializer<'a> {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
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::Option(false)) => visitor.visit_none(),
Some(Token::Option(true)) => visitor.visit_some(self),
Some(Token::Unit) => visitor.visit_unit(),
Some(Token::NamedUnit(name)) => visitor.visit_named_unit(name),
Some(Token::SeqStart(len)) => {
visitor.visit_seq(TokenDeserializerSeqVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::NamedSeqStart(name, len)) => {
visitor.visit_named_seq(name, TokenDeserializerSeqVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::MapStart(len)) => {
visitor.visit_map(TokenDeserializerMapVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::NamedMapStart(name, len)) => {
visitor.visit_named_map(name, TokenDeserializerMapVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::EnumStart(name, variant)) => {
visitor.visit_enum(name, variant, TokenDeserializerEnumVisitor {
de: self,
})
}
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)`.
#[inline]
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
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),
}
}
}
//////////////////////////////////////////////////////////////////////////
struct TokenDeserializerSeqVisitor<'a, 'b: 'a> {
de: &'a mut TokenDeserializer<'b>,
len: usize,
first: bool,
}
impl<'a, 'b> de::SeqVisitor for TokenDeserializerSeqVisitor<'a, 'b> {
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: Deserialize,
{
let first = self.first;
self.first = false;
match self.de.tokens.next() {
Some(Token::SeqSep(first_)) if first_ == first => {
self.len -= 1;
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> {
match self.de.tokens.next() {
Some(Token::SeqEnd) => Ok(()),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
//////////////////////////////////////////////////////////////////////////
struct TokenDeserializerMapVisitor<'a, 'b: 'a> {
de: &'a mut TokenDeserializer<'b>,
len: usize,
first: bool,
}
impl<'a, 'b> de::MapVisitor for TokenDeserializerMapVisitor<'a, 'b> {
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
where K: Deserialize,
{
let first = self.first;
self.first = false;
match self.de.tokens.next() {
Some(Token::MapSep(first_)) if first_ == first => {
Ok(Some(try!(Deserialize::deserialize(self.de))))
}
Some(Token::MapEnd) => Ok(None),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn visit_value<V>(&mut self) -> Result<V, Error>
where V: Deserialize,
{
Ok(try!(Deserialize::deserialize(self.de)))
}
fn end(&mut self) -> Result<(), Error> {
match self.de.tokens.next() {
Some(Token::MapEnd) => Ok(()),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
//////////////////////////////////////////////////////////////////////////
struct TokenDeserializerEnumVisitor<'a, 'b: 'a> {
de: &'a mut TokenDeserializer<'b>,
}
impl<'a, 'b> de::EnumVisitor for TokenDeserializerEnumVisitor<'a, 'b> {
type Error = Error;
fn visit_unit(&mut self) -> Result<(), Error> {
let value = try!(Deserialize::deserialize(self.de));
match self.de.tokens.next() {
Some(Token::EnumEnd) => Ok(value),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
{
let token = self.de.tokens.next();
match token {
Some(Token::SeqStart(len)) => {
let value = try!(visitor.visit(TokenDeserializerSeqVisitor {
de: self.de,
len: len,
first: true,
}));
match self.de.tokens.next() {
Some(Token::EnumEnd) => Ok(value),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor,
{
match self.de.tokens.next() {
Some(Token::MapStart(len)) => {
let value = try!(visitor.visit(TokenDeserializerMapVisitor {
de: self.de,
len: len,
first: true,
}));
match self.de.tokens.next() {
Some(Token::EnumEnd) => Ok(value),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
}
//////////////////////////////////////////////////////////////////////////
#[derive(Copy, PartialEq, Debug)]
#[derive_deserialize]
struct NamedUnit;
#[derive(PartialEq, Debug)]
#[derive_deserialize]
struct NamedSeq(i32, i32, i32);
#[derive(PartialEq, Debug)]
#[derive_deserialize]
struct NamedMap {
a: i32,
b: i32,
c: i32,
}
#[derive(PartialEq, Debug)]
#[derive_deserialize]
enum Enum {
Unit,
Seq(i32, i32, i32),
Map { a: i32, b: i32, c: i32 }
}
//////////////////////////////////////////////////////////////////////////
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 de = TokenDeserializer::new($tokens);
let value: Result<_, Error> = Deserialize::deserialize(&mut de);
assert_eq!(value, Ok($value));
)+
}
}
}
macro_rules! declare_tests {
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
$(
declare_test!($name { $($value => $tokens,)+ });
)+
}
}
//////////////////////////////////////////////////////////////////////////
declare_tests! {
test_bool {
true => vec![Token::Bool(true)],
false => vec![Token::Bool(false)],
}
test_isize {
0isize => vec![Token::Isize(0)],
0isize => vec![Token::I8(0)],
0isize => vec![Token::I16(0)],
0isize => vec![Token::I32(0)],
0isize => vec![Token::I64(0)],
0isize => vec![Token::Usize(0)],
0isize => vec![Token::U8(0)],
0isize => vec![Token::U16(0)],
0isize => vec![Token::U32(0)],
0isize => vec![Token::U64(0)],
0isize => vec![Token::F32(0.)],
0isize => vec![Token::F64(0.)],
}
test_ints {
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)],
}
test_uints {
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)],
}
test_floats {
0f32 => vec![Token::F32(0.)],
0f64 => vec![Token::F64(0.)],
}
test_char {
'a' => vec![Token::Char('a')],
'a' => vec![Token::Str("a")],
'a' => vec![Token::String("a".to_string())],
}
test_string {
"abc".to_string() => vec![Token::Str("abc")],
"abc".to_string() => vec![Token::String("abc".to_string())],
"a".to_string() => vec![Token::Char('a')],
}
test_option {
None::<i32> => vec![Token::Unit],
None::<i32> => vec![Token::Option(false)],
Some(1) => vec![Token::I32(1)],
Some(1) => vec![
Token::Option(true),
Token::I32(1),
],
}
test_unit {
() => vec![Token::Unit],
() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
() => vec![
Token::NamedSeqStart("Anything", 0),
Token::SeqEnd,
],
}
test_named_unit {
NamedUnit => vec![Token::Unit],
NamedUnit => vec![Token::NamedUnit("NamedUnit")],
NamedUnit => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_named_seq {
NamedSeq(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::I32(1),
Token::SeqSep(false),
Token::I32(2),
Token::SeqSep(false),
Token::I32(3),
Token::SeqEnd,
],
NamedSeq(1, 2, 3) => vec![
Token::NamedSeqStart("NamedSeq", 3),
Token::SeqSep(true),
Token::I32(1),
Token::SeqSep(false),
Token::I32(2),
Token::SeqSep(false),
Token::I32(3),
Token::SeqEnd,
],
}
test_vec {
Vec::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
vec![vec![], vec![1], vec![2, 3]] => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqStart(0),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqStart(1),
Token::SeqSep(true),
Token::I32(1),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqStart(2),
Token::SeqSep(true),
Token::I32(2),
Token::SeqSep(false),
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
],
}
test_tuple {
(1,) => vec![
Token::SeqStart(1),
Token::SeqSep(true),
Token::I32(1),
Token::SeqEnd,
],
(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::I32(1),
Token::SeqSep(false),
Token::I32(2),
Token::SeqSep(false),
Token::I32(3),
Token::SeqEnd,
],
}
test_btreemap {
btreemap![1 => 2] => vec![
Token::MapStart(1),
Token::MapSep(true),
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
btreemap![1 => 2, 3 => 4] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::I32(1),
Token::I32(2),
Token::MapSep(false),
Token::I32(3),
Token::I32(4),
Token::MapEnd,
],
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::I32(1),
Token::MapStart(0),
Token::MapEnd,
Token::MapSep(false),
Token::I32(2),
Token::MapStart(2),
Token::MapSep(true),
Token::I32(3),
Token::I32(4),
Token::MapSep(false),
Token::I32(5),
Token::I32(6),
Token::MapEnd,
Token::MapEnd,
],
}
test_named_map {
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::MapStart(3),
Token::MapSep(true),
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
],
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::NamedMapStart("NamedMap", 3),
Token::MapSep(true),
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
],
}
test_enum {
Enum::Unit => vec![
Token::EnumStart("Enum", "Unit"),
Token::Unit,
Token::EnumEnd,
],
}
test_enum_seq {
Enum::Seq(1, 2, 3) => vec![
Token::EnumStart("Enum", "Seq"),
Token::SeqStart(3),
Token::SeqSep(true),
Token::I32(1),
Token::SeqSep(false),
Token::I32(2),
Token::SeqSep(false),
Token::I32(3),
Token::SeqEnd,
Token::EnumEnd,
],
}
test_enum_map {
Enum::Map { a: 1, b: 2, c: 3 } => vec![
Token::EnumStart("Enum", "Map"),
Token::MapStart(3),
Token::MapSep(true),
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
Token::EnumEnd,
],
}
}
+761
View File
@@ -0,0 +1,761 @@
#![feature(custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate test;
extern crate serde;
use std::fmt::Debug;
use std::collections::BTreeMap;
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(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
enum Animal {
Dog,
Frog(String, Vec<isize>),
Cat { age: usize, name: String },
}
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
struct Inner {
a: (),
b: usize,
c: Vec<String>,
}
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
struct Outer {
inner: Vec<Inner>,
}
fn test_encode_ok<T>(errors: &[(T, &str)])
where T: PartialEq + Debug + ser::Serialize,
{
for &(ref value, out) in errors {
let out = out.to_string();
let s = json::to_string(value).unwrap();
assert_eq!(s, out);
let v = to_value(&value);
let s = json::to_string(&v).unwrap();
assert_eq!(s, out);
}
}
fn test_pretty_encode_ok<T>(errors: &[(T, &str)])
where T: PartialEq + Debug + ser::Serialize,
{
for &(ref value, out) in errors {
let out = out.to_string();
let s = json::to_string_pretty(value).unwrap();
assert_eq!(s, out);
let v = to_value(&value);
let s = 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_i64() {
let tests = &[
(3i64, "3"),
(-2i64, "-2"),
(-1234i64, "-1234"),
];
test_encode_ok(tests);
test_pretty_encode_ok(tests);
}
#[test]
fn test_write_f64() {
let tests = &[
(3.0, "3"),
(3.1, "3.1"),
(-1.5, "-1.5"),
(0.5, "0.5"),
];
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_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_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\"}}"
),
]);
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<'a, T>(errors: &[(&'a str, T)])
where T: PartialEq + Debug + ser::Serialize + de::Deserialize,
{
for &(s, ref value) in errors {
let v: T = from_str(s).unwrap();
assert_eq!(v, *value);
// 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_value, json_value2);
}
}
// FIXME (#5527): these could be merged once UFCS is finished.
fn test_parse_err<'a, T>(errors: &[(&'a str, Error)])
where T: Debug + de::Deserialize,
{
for &(s, ref err) in errors {
let v: Result<T, Error> = from_str(s);
assert_eq!(v.unwrap_err(), *err);
}
}
#[test]
fn test_parse_null() {
test_parse_err::<()>(&[
("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
]);
test_parse_ok(&[
("null", ()),
]);
}
#[test]
fn test_parse_bool() {
test_parse_err::<bool>(&[
("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
("faz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
]);
test_parse_ok(&[
("true", true),
(" true ", true),
("false", false),
(" false ", false),
]);
}
#[test]
fn test_parse_number_errors() {
test_parse_err::<f64>(&[
("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
(".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
("00", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 4)),
("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
]);
}
#[test]
fn test_parse_i64() {
test_parse_ok(&[
("3", 3),
("-2", -2),
("-1234", -1234),
(" -1234 ", -1234),
]);
}
#[test]
fn test_parse_f64() {
test_parse_ok(&[
("3.0", 3.0f64),
("3.1", 3.1),
("-1.2", -1.2),
("0.4", 0.4),
("0.4e5", 0.4e5),
("0.4e15", 0.4e15),
("0.4e-01", 0.4e-01),
(" 0.4e-01 ", 0.4e-01),
]);
}
#[test]
fn test_parse_string() {
test_parse_err::<String>(&[
("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)),
("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)),
("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
]);
test_parse_ok(&[
("\"\"", "".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<f64>>(&[
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 3)),
("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 4)),
("[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![]),
("[null]", vec![()]),
(" [ null ] ", vec![()]),
]);
test_parse_ok(&[
("[true]", vec![true]),
]);
test_parse_ok(&[
("[3,1]", vec![3, 1]),
(" [ 3 , 1 ] ", vec![3, 1]),
]);
test_parse_ok(&[
("[[3], [1, 2]]", vec![vec![3], vec![1, 2]]),
]);
test_parse_ok(&[
("[1]", (1,)),
]);
test_parse_ok(&[
("[1, 2]", (1, 2)),
]);
test_parse_ok(&[
("[1, 2, 3]", (1, 2, 3)),
]);
test_parse_ok(&[
("[1, [2, 3]]", (1, (2, 3))),
]);
let v: () = from_str("[]").unwrap();
assert_eq!(v, ());
}
#[test]
fn test_parse_object() {
test_parse_err::<BTreeMap<String, u32>>(&[
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)),
("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)),
("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 6)),
("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 7)),
("{\"a\":1 1", Error::SyntaxError(ErrorCode::ExpectedObjectCommaOrEnd, 1, 8)),
("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)),
("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
]);
test_parse_ok(&[
("{}", treemap!()),
("{ }", treemap!()),
(
"{\"a\":3}",
treemap!("a".to_string() => 3)
),
(
"{ \"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(&[
(
"{\"a\": {\"b\": 3, \"c\": 4}}",
treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)),
),
]);
}
#[test]
fn test_parse_struct() {
test_parse_err::<Outer>(&[
("[]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{}", Error::MissingFieldError("inner")),
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
]);
test_parse_ok(&[
(
"{
\"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()] }
]
},
)
]);
}
#[test]
fn test_parse_option() {
test_parse_ok(&[
("null", None::<String>),
("\"jodhpurs\"", Some("jodhpurs".to_string())),
]);
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
struct Foo {
x: Option<isize>,
}
/*
let value: Foo = from_str("{}").unwrap();
assert_eq!(value, Foo { x: None });
*/
test_parse_ok(&[
("{\"x\": null}", Foo { x: None }),
("{\"x\": 5}", Foo { x: Some(5) }),
]);
}
#[test]
fn test_parse_enum() {
test_parse_err::<Animal>(&[
("{}", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 3)),
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
]);
test_parse_ok(&[
("{\"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() },
),
]);
test_parse_ok(&[
(
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(&[
("[1, 2] ", vec![1, 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::<BTreeMap<String, String>>(&[
("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 8)),
]);
}
+52
View File
@@ -0,0 +1,52 @@
extern crate serde;
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::I64(1), Value::I64(2), Value::I64(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::I64(1), Value::I64(2), Value::I64(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::I64(1));
map.insert("b".to_string(), Value::I64(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::I64(1));
map.insert("b".to_string(), Value::I64(2));
assert_eq!(value, Value::Object(map));
}
+406
View File
@@ -0,0 +1,406 @@
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
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
}
}
}
/*
trait Trait {
type Type;
}
*/
#[derive(Debug, PartialEq)]
#[derive_serialize]
#[derive_deserialize]
struct NamedUnit;
#[derive(Debug, PartialEq)]
#[derive_serialize]
enum SerEnum<'a, B: 'a, C: /* Trait + */ 'a, D> where D: /* Trait + */ 'a {
Unit,
Seq(
i8,
B,
&'a C,
//C::Type,
&'a mut D,
//<D as Trait>::Type,
),
Map {
a: i8,
b: B,
c: &'a C,
//d: C::Type,
e: &'a mut D,
//f: <D as Trait>::Type,
},
}
#[derive(Debug, PartialEq)]
#[derive_deserialize]
enum DeEnum<B, C: /* Trait */, D> /* where D: Trait */ {
Unit,
Seq(
i8,
B,
C,
//C::Type,
D,
//<D as Trait>::Type,
),
Map {
a: i8,
b: B,
c: C,
//d: C::Type,
e: D,
//f: <D as Trait>::Type,
},
}
#[test]
fn test_named_unit() {
let named_unit = NamedUnit;
assert_eq!(
json::to_string(&named_unit).unwrap(),
"null".to_string()
);
assert_eq!(
json::to_value(&named_unit),
Value::Null
);
let v = json::from_str("null").unwrap();
assert_eq!(v, named_unit);
let v = json::from_value(Value::Null).unwrap();
assert_eq!(v, named_unit);
}
#[test]
fn test_ser_named_tuple() {
#[derive(Debug, PartialEq)]
#[derive_serialize]
struct NamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
let a = 5;
let mut b = 6;
let c = 7;
let named_tuple = NamedTuple(&a, &mut b, c);
assert_eq!(
json::to_string(&named_tuple).unwrap(),
"[5,6,7]"
);
assert_eq!(
json::to_value(&named_tuple),
Value::Array(vec![Value::I64(5), Value::I64(6), Value::I64(7)])
);
}
#[test]
fn test_de_named_tuple() {
#[derive(Debug, PartialEq)]
#[derive_deserialize]
struct NamedTuple<A, B, C>(A, B, C);
assert_eq!(
json::from_str("[1,2,3]").unwrap(),
NamedTuple(1, 2, 3)
);
assert_eq!(
json::from_str("[1,2,3]").unwrap(),
Value::Array(vec![
Value::I64(1),
Value::I64(2),
Value::I64(3),
])
);
}
#[test]
fn test_ser_named_map() {
#[derive(Debug, PartialEq)]
#[derive_serialize]
struct NamedMap<'a, 'b, A: 'a, B: 'b, C> {
a: &'a A,
b: &'b mut B,
c: C,
}
let a = 5;
let mut b = 6;
let c = 7;
let named_map = NamedMap {
a: &a,
b: &mut b,
c: c,
};
assert_eq!(
json::to_string(&named_map).unwrap(),
"{\"a\":5,\"b\":6,\"c\":7}"
);
assert_eq!(
json::to_value(&named_map),
Value::Object(btreemap![
"a".to_string() => Value::I64(5),
"b".to_string() => Value::I64(6),
"c".to_string() => Value::I64(7)
])
);
}
#[test]
fn test_de_named_map() {
#[derive(Debug, PartialEq)]
#[derive_deserialize]
struct NamedMap<A, B, C> {
a: A,
b: B,
c: C,
}
let v = NamedMap {
a: 5,
b: 6,
c: 7,
};
assert_eq!(
json::from_str("{\"a\":5,\"b\":6,\"c\":7}").unwrap(),
v
);
assert_eq!(
json::from_value(Value::Object(btreemap![
"a".to_string() => Value::I64(5),
"b".to_string() => Value::I64(6),
"c".to_string() => Value::I64(7)
])).unwrap(),
v
);
}
#[test]
fn test_ser_enum_unit() {
assert_eq!(
json::to_string(&SerEnum::Unit::<u32, u32, u32>).unwrap(),
"{\"Unit\":[]}"
);
assert_eq!(
json::to_value(&SerEnum::Unit::<u32, u32, u32>),
Value::Object(btreemap!(
"Unit".to_string() => Value::Array(vec![]))
)
);
}
#[test]
fn test_ser_enum_seq() {
let a = 1;
let b = 2;
let c = 3;
//let d = 4;
let mut e = 5;
//let f = 6;
assert_eq!(
json::to_string(&SerEnum::Seq(
a,
b,
&c,
//d,
&mut e,
//f,
)).unwrap(),
"{\"Seq\":[1,2,3,5]}".to_string()
);
assert_eq!(
json::to_value(&SerEnum::Seq(
a,
b,
&c,
//d,
&mut e,
//e,
)),
Value::Object(btreemap!(
"Seq".to_string() => Value::Array(vec![
Value::I64(1),
Value::I64(2),
Value::I64(3),
//Value::I64(4),
Value::I64(5),
//Value::I64(6),
])
))
);
}
#[test]
fn test_ser_enum_map() {
let a = 1;
let b = 2;
let c = 3;
//let d = 4;
let mut e = 5;
//let f = 6;
assert_eq!(
json::to_string(&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()
);
assert_eq!(
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::I64(1),
"b".to_string() => Value::I64(2),
"c".to_string() => Value::I64(3),
//"d".to_string() => Value::I64(4)
"e".to_string() => Value::I64(5)
//"f".to_string() => Value::I64(6)
])
))
);
}
#[test]
fn test_de_enum_unit() {
assert_eq!(
json::from_str("{\"Unit\":[]}").unwrap(),
DeEnum::Unit::<u32, u32, u32>
);
assert_eq!(
json::from_value(Value::Object(btreemap!(
"Unit".to_string() => Value::Array(vec![]))
)).unwrap(),
DeEnum::Unit::<u32, u32, u32>
);
}
#[test]
fn test_de_enum_seq() {
let a = 1;
let b = 2;
let c = 3;
//let d = 4;
let e = 5;
//let f = 6;
assert_eq!(
json::from_str("{\"Seq\":[1,2,3,5]}").unwrap(),
DeEnum::Seq(
a,
b,
c,
//d,
e,
//f,
)
);
assert_eq!(
json::from_value(Value::Object(btreemap!(
"Seq".to_string() => Value::Array(vec![
Value::I64(1),
Value::I64(2),
Value::I64(3),
//Value::I64(4),
Value::I64(5),
//Value::I64(6),
])
))).unwrap(),
DeEnum::Seq(
a,
b,
c,
//d,
e,
//e,
)
);
}
#[test]
fn test_de_enum_map() {
let a = 1;
let b = 2;
let c = 3;
//let d = 4;
let e = 5;
//let f = 6;
assert_eq!(
json::from_str("{\"Map\":{\"a\":1,\"b\":2,\"c\":3,\"e\":5}}").unwrap(),
DeEnum::Map {
a: a,
b: b,
c: c,
//d: d,
e: e,
//f: f,
}
);
assert_eq!(
json::from_value(Value::Object(btreemap!(
"Map".to_string() => Value::Object(btreemap![
"a".to_string() => Value::I64(1),
"b".to_string() => Value::I64(2),
"c".to_string() => Value::I64(3),
//"d".to_string() => Value::I64(4)
"e".to_string() => Value::I64(5)
//"f".to_string() => Value::I64(6)
])
))).unwrap(),
DeEnum::Map {
a: a,
b: b,
c: c,
//d: d,
e: e,
//f: f,
}
);
}
+544
View File
@@ -0,0 +1,544 @@
#![feature(custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate test;
extern crate serde;
use std::vec;
use std::collections::BTreeMap;
use serde::ser::{Serialize, Serializer, Visitor, 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,
NamedUnit(&'a str),
EnumUnit(&'a str, &'a str),
SeqStart(usize),
NamedSeqStart(&'a str, usize),
EnumSeqStart(&'a str, &'a str, usize),
SeqSep(bool),
SeqEnd,
MapStart(usize),
NamedMapStart(&'a str, usize),
EnumMapStart(&'a str, &'a str, usize),
MapSep(bool),
MapEnd,
}
struct AssertSerializer<'a> {
iter: vec::IntoIter<Token<'a>>,
}
impl<'a> AssertSerializer<'a> {
fn new(values: Vec<Token<'a>>) -> AssertSerializer {
AssertSerializer {
iter: values.into_iter(),
}
}
fn visit_sequence<V>(&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<V>(&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 Value = ();
type Error = ();
fn visit<T: Serialize>(&mut self, value: &T) -> Result<(), ()> {
value.visit(self)
}
}
impl<'a> Visitor for AssertSerializer<'a> {
type Value = ();
type Error = ();
fn visit_unit(&mut self) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::Unit));
Ok(())
}
fn visit_named_unit(&mut self, name: &str) -> Result<(), ()> {
assert_eq!(self.iter.next().unwrap(), Token::NamedUnit(name));
Ok(())
}
fn visit_enum_unit(&mut self, name: &str, 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<V>(&mut self, value: V) -> Result<(), ()>
where V: Serialize,
{
assert_eq!(self.iter.next(), Some(Token::Option(true)));
value.visit(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let (len, _) = visitor.size_hint();
assert_eq!(self.iter.next(), Some(Token::SeqStart(len)));
self.visit_sequence(visitor)
}
fn visit_named_seq<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let (len, _) = visitor.size_hint();
assert_eq!(self.iter.next().unwrap(), Token::NamedSeqStart(name, len));
self.visit_sequence(visitor)
}
fn visit_enum_seq<V>(&mut self,
name: &str,
variant: &str,
visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let (len, _) = visitor.size_hint();
assert_eq!(self.iter.next().unwrap(), Token::EnumSeqStart(name, variant, len));
self.visit_sequence(visitor)
}
fn visit_seq_elt<T>(&mut self, first: bool, value: T) -> Result<(), ()>
where T: Serialize
{
assert_eq!(self.iter.next(), Some(Token::SeqSep(first)));
value.visit(self)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let (len, _) = visitor.size_hint();
assert_eq!(self.iter.next(), Some(Token::MapStart(len)));
self.visit_mapping(visitor)
}
fn visit_named_map<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let (len, _) = visitor.size_hint();
assert_eq!(self.iter.next().unwrap(), Token::NamedMapStart(name, len));
self.visit_mapping(visitor)
}
fn visit_enum_map<V>(&mut self,
name: &str,
variant: &str,
visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let (len, _) = visitor.size_hint();
assert_eq!(self.iter.next().unwrap(), Token::EnumMapStart(name, variant, len));
self.visit_mapping(visitor)
}
fn visit_map_elt<K, V>(&mut self,
first: bool,
key: K,
value: V) -> Result<(), ()>
where K: Serialize,
V: Serialize,
{
assert_eq!(self.iter.next(), Some(Token::MapSep(first)));
try!(key.visit(self));
value.visit(self)
}
}
//////////////////////////////////////////////////////////////////////////
#[derive_serialize]
struct NamedUnit;
#[derive_serialize]
struct NamedSeq(i32, i32, i32);
#[derive_serialize]
struct NamedMap {
a: i32,
b: i32,
c: i32,
}
#[derive_serialize]
enum Enum {
Unit,
Seq(i32, i32),
Map { a: i32, b: i32 },
}
//////////////////////////////////////////////////////////////////////////
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!(ser.visit(&$value), Ok(()));
)+
}
}
}
macro_rules! declare_tests {
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
$(
declare_test!($name { $($value => $tokens,)+ });
)+
}
}
declare_tests! {
test_unit {
() => vec![Token::Unit],
}
test_bool {
true => vec![Token::Bool(true)],
false => vec![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)],
}
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)],
}
test_floats {
0f32 => vec![Token::F32(0.)],
0f64 => vec![Token::F64(0.)],
}
test_char {
'a' => vec![Token::Char('a')],
}
test_str {
"abc" => vec![Token::Str("abc")],
"abc".to_string() => vec![Token::Str("abc")],
}
test_option {
None::<i32> => vec![Token::Option(false)],
Some(1) => vec![
Token::Option(true),
Token::I32(1),
],
}
test_slice {
&[0][..0] => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
&[1, 2, 3][..] => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::I32(1),
Token::SeqSep(false),
Token::I32(2),
Token::SeqSep(false),
Token::I32(3),
Token::SeqEnd,
],
}
test_vec {
Vec::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
vec![vec![], vec![1], vec![2, 3]] => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqStart(0),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqStart(1),
Token::SeqSep(true),
Token::I32(1),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqStart(2),
Token::SeqSep(true),
Token::I32(2),
Token::SeqSep(false),
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
],
}
test_tuple {
(1,) => vec![
Token::SeqStart(1),
Token::SeqSep(true),
Token::I32(1),
Token::SeqEnd,
],
(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::I32(1),
Token::SeqSep(false),
Token::I32(2),
Token::SeqSep(false),
Token::I32(3),
Token::SeqEnd,
],
}
test_btreemap {
btreemap![1 => 2] => vec![
Token::MapStart(1),
Token::MapSep(true),
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
btreemap![1 => 2, 3 => 4] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::I32(1),
Token::I32(2),
Token::MapSep(false),
Token::I32(3),
Token::I32(4),
Token::MapEnd,
],
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::I32(1),
Token::MapStart(0),
Token::MapEnd,
Token::MapSep(false),
Token::I32(2),
Token::MapStart(2),
Token::MapSep(true),
Token::I32(3),
Token::I32(4),
Token::MapSep(false),
Token::I32(5),
Token::I32(6),
Token::MapEnd,
Token::MapEnd,
],
}
test_named_unit {
NamedUnit => vec![Token::NamedUnit("NamedUnit")],
}
test_named_seq {
NamedSeq(1, 2, 3) => vec![
Token::NamedSeqStart("NamedSeq", 3),
Token::SeqSep(true),
Token::I32(1),
Token::SeqSep(false),
Token::I32(2),
Token::SeqSep(false),
Token::I32(3),
Token::SeqEnd,
],
}
test_named_map {
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::NamedMapStart("NamedMap", 3),
Token::MapSep(true),
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
],
}
test_enum {
Enum::Unit => vec![Token::EnumUnit("Enum", "Unit")],
Enum::Seq(1, 2) => vec![
Token::EnumSeqStart("Enum", "Seq", 2),
Token::SeqSep(true),
Token::I32(1),
Token::SeqSep(false),
Token::I32(2),
Token::SeqEnd,
],
Enum::Map { a: 1, b: 2 } => vec![
Token::EnumMapStart("Enum", "Map", 2),
Token::MapSep(true),
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::Str("b"),
Token::I32(2),
Token::MapEnd,
],
}
}