Simplify the variant deserializer visitor

This commit is contained in:
Erick Tryzelaar 2015-03-18 07:35:05 -07:00
parent 78137ee3a4
commit eb4af09456
7 changed files with 131 additions and 236 deletions

View File

@ -340,20 +340,10 @@ mod deserializer {
de::Deserialize::deserialize(self.de) de::Deserialize::deserialize(self.de)
} }
fn visit_unit(&mut self) -> Result<(), Error> { fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
de::Deserialize::deserialize(self.de) where V: de::Visitor,
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor
{ {
Err(de::Error::syntax_error()) de::Deserializer::visit(self.de, visitor)
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor
{
Err(de::Error::syntax_error())
} }
} }
@ -371,20 +361,10 @@ mod deserializer {
de::Deserialize::deserialize(self.de) de::Deserialize::deserialize(self.de)
} }
fn visit_unit(&mut self) -> Result<(), Error> { fn visit_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
Err(de::Error::syntax_error()) where V: de::Visitor,
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
{ {
visitor.visit(self) visitor.visit_seq(self)
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor
{
Err(de::Error::syntax_error())
} }
} }

View File

@ -454,7 +454,7 @@ fn deserialize_variant(
match variant.node.kind { match variant.node.kind {
ast::TupleVariantKind(ref args) if args.is_empty() => { ast::TupleVariantKind(ref args) if args.is_empty() => {
quote_expr!(cx, { quote_expr!(cx, {
try!(visitor.visit_unit()); try!(visitor.visit_value(::serde::de::UnitVisitor));
Ok($type_ident::$variant_ident) Ok($type_ident::$variant_ident)
}) })
} }
@ -509,17 +509,17 @@ fn deserialize_tuple_variant(
quote_expr!(cx, { quote_expr!(cx, {
$visitor_item $visitor_item
impl $generics ::serde::de::EnumSeqVisitor for $visitor_ty $where_clause { impl $generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty; type Value = $ty;
fn visit< fn visit_seq<__V>(&mut self, mut visitor: __V) -> Result<$ty, __V::Error>
V: ::serde::de::SeqVisitor, where __V: ::serde::de::SeqVisitor,
>(&mut self, mut visitor: V) -> Result<$ty, V::Error> { {
$visit_seq_expr $visit_seq_expr
} }
} }
visitor.visit_seq($visitor_expr) visitor.visit_value($visitor_expr)
}) })
} }
@ -551,17 +551,17 @@ fn deserialize_struct_variant(
$visitor_item $visitor_item
impl $generics ::serde::de::EnumMapVisitor for $visitor_ty $where_clause { impl $generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty; type Value = $ty;
fn visit< fn visit_map<__V>(&mut self, mut visitor: __V) -> Result<$ty, __V::Error>
V: ::serde::de::MapVisitor, where __V: ::serde::de::MapVisitor,
>(&mut self, mut visitor: V) -> Result<$ty, V::Error> { {
$field_expr $field_expr
} }
} }
visitor.visit_map($visitor_expr) visitor.visit_value($visitor_expr)
}) })
} }

View File

@ -15,11 +15,15 @@ pub trait Error {
fn missing_field_error(&'static str) -> Self; fn missing_field_error(&'static str) -> Self;
} }
///////////////////////////////////////////////////////////////////////////////
pub trait Deserialize { pub trait Deserialize {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer; where D: Deserializer;
} }
///////////////////////////////////////////////////////////////////////////////
pub trait Deserializer { pub trait Deserializer {
type Error: Error; type Error: Error;
@ -50,6 +54,8 @@ pub trait Deserializer {
} }
} }
///////////////////////////////////////////////////////////////////////////////
pub trait Visitor { pub trait Visitor {
type Value; type Value;
@ -335,13 +341,8 @@ pub trait VariantVisitor {
fn visit_variant<V>(&mut self) -> Result<V, Self::Error> fn visit_variant<V>(&mut self) -> Result<V, Self::Error>
where V: Deserialize; where V: Deserialize;
fn visit_unit(&mut self) -> Result<(), Self::Error>; fn visit_value<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor;
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: EnumSeqVisitor;
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: EnumMapVisitor;
} }
impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor { impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
@ -353,21 +354,10 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
(**self).visit_variant() (**self).visit_variant()
} }
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{ {
fn visit_unit(&mut self) -> Result<(), T::Error> { (**self).visit_value(visitor)
(**self).visit_unit()
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: EnumSeqVisitor
{
(**self).visit_seq(visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: EnumMapVisitor
{
(**self).visit_map(visitor)
} }
} }
@ -391,7 +381,7 @@ pub trait EnumMapVisitor {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
struct UnitVisitor; pub struct UnitVisitor;
impl Visitor for UnitVisitor { impl Visitor for UnitVisitor {
type Value = (); type Value = ();

View File

@ -604,48 +604,12 @@ impl<Iter> de::VariantVisitor for Deserializer<Iter>
de::Deserialize::deserialize(self) de::Deserialize::deserialize(self)
} }
/* fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_value<V>(&mut self) -> Result<V, Error> where V: de::Visitor,
where V: de::Deserialize
{
de::Deserialize::deserialize(self)
}
*/
fn visit_unit(&mut self) -> Result<(), Error> {
try!(self.parse_object_colon());
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor
{ {
try!(self.parse_object_colon()); try!(self.parse_object_colon());
self.parse_whitespace(); de::Deserializer::visit(self, visitor)
if self.ch_is(b'[') {
self.bump();
visitor.visit(SeqVisitor::new(self))
} else {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
}
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor
{
try!(self.parse_object_colon());
self.parse_whitespace();
if self.ch_is(b'{') {
self.bump();
visitor.visit(MapVisitor::new(self))
} else {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
} }
} }

View File

@ -443,13 +443,11 @@ impl de::Deserializer for Deserializer {
})) }))
} }
Some((variant, Value::Object(fields))) => { Some((variant, Value::Object(fields))) => {
self.value = Some(Value::String(variant));
let len = fields.len(); let len = fields.len();
try!(visitor.visit(MapDeserializer { try!(visitor.visit(MapDeserializer {
de: self, de: self,
iter: fields.into_iter(), iter: fields.into_iter(),
value: None, value: Some(Value::String(variant)),
len: len, len: len,
})) }))
} }
@ -470,6 +468,21 @@ struct SeqDeserializer<'a> {
len: usize, len: usize,
} }
impl<'a> de::Deserializer for SeqDeserializer<'a> {
type Error = Error;
#[inline]
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
if self.len == 0 {
visitor.visit_unit()
} else {
visitor.visit_seq(self)
}
}
}
impl<'a> de::SeqVisitor for SeqDeserializer<'a> { impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
type Error = Error; type Error = Error;
@ -508,24 +521,10 @@ impl<'a> de::VariantVisitor for SeqDeserializer<'a> {
de::Deserialize::deserialize(self.de) de::Deserialize::deserialize(self.de)
} }
fn visit_unit(&mut self) -> Result<(), Error> { fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
if self.len == 0 { where V: de::Visitor,
Ok(())
} else {
Err(de::Error::syntax_error())
}
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
{ {
visitor.visit(self) de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor
{
Err(de::Error::syntax_error())
} }
} }
@ -599,29 +598,32 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> {
} }
} }
impl<'a> de::Deserializer for MapDeserializer<'a> {
type Error = Error;
#[inline]
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
println!("MapDeserializer!");
visitor.visit_map(self)
}
}
impl<'a> de::VariantVisitor for MapDeserializer<'a> { impl<'a> de::VariantVisitor for MapDeserializer<'a> {
type Error = Error; type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error> fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize, where V: de::Deserialize,
{ {
self.de.value = self.value.take();
de::Deserialize::deserialize(self.de) de::Deserialize::deserialize(self.de)
} }
fn visit_unit(&mut self) -> Result<(), Error> { fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
Err(de::Error::syntax_error()) where V: de::Visitor,
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor
{ {
Err(de::Error::syntax_error()) de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor,
{
visitor.visit(self)
} }
} }

View File

@ -282,65 +282,16 @@ struct TokenDeserializerVariantVisitor<'a, 'b: 'a> {
impl<'a, 'b> de::VariantVisitor for TokenDeserializerVariantVisitor<'a, 'b> { impl<'a, 'b> de::VariantVisitor for TokenDeserializerVariantVisitor<'a, 'b> {
type Error = Error; type Error = Error;
fn visit_kind<V>(&mut self) -> Result<V, Error> fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize, where V: de::Deserialize,
{ {
de::Deserialize::deserialize(self.de) de::Deserialize::deserialize(self.de)
} }
fn visit_unit(&mut self) -> Result<(), Error> { fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
let value = try!(Deserialize::deserialize(self.de)); where V: de::Visitor,
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(); de::Deserializer::visit(self.de, visitor)
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),
}
} }
} }

View File

@ -28,7 +28,7 @@ macro_rules! treemap {
}) })
} }
#[derive(PartialEq, Debug)] #[derive(Clone, Debug, PartialEq)]
#[derive_serialize] #[derive_serialize]
#[derive_deserialize] #[derive_deserialize]
enum Animal { enum Animal {
@ -38,7 +38,7 @@ enum Animal {
} }
#[derive(PartialEq, Debug)] #[derive(Clone, Debug, PartialEq)]
#[derive_serialize] #[derive_serialize]
#[derive_deserialize] #[derive_deserialize]
struct Inner { struct Inner {
@ -47,7 +47,7 @@ struct Inner {
c: Vec<String>, c: Vec<String>,
} }
#[derive(PartialEq, Debug)] #[derive(Clone, Debug, PartialEq)]
#[derive_serialize] #[derive_serialize]
#[derive_deserialize] #[derive_deserialize]
struct Outer { struct Outer {
@ -628,53 +628,56 @@ fn test_write_option() {
]); ]);
} }
fn test_parse_ok<'a, T>(errors: &[(&'a str, T)]) fn test_parse_ok<T>(errors: Vec<(&'static str, T)>)
where T: PartialEq + Debug + ser::Serialize + de::Deserialize, where T: Clone + Debug + PartialEq + ser::Serialize + de::Deserialize,
{ {
for &(s, ref value) in errors { for (s, value) in errors {
let v: T = from_str(s).unwrap(); let v: Result<T, Error> = from_str(s);
assert_eq!(v, *value); assert_eq!(v, Ok(value.clone()));
// Make sure we can deserialize into a `Value`. // Make sure we can deserialize into a `Value`.
let json_value: Value = from_str(s).unwrap(); let json_value: Result<Value, Error> = from_str(s);
assert_eq!(json_value, to_value(&value)); assert_eq!(json_value, Ok(to_value(&value)));
let json_value = json_value.unwrap();
// Make sure we can deserialize from a `Value`. // Make sure we can deserialize from a `Value`.
let v: T = from_value(json_value.clone()).unwrap(); let v: Result<T, Error> = from_value(json_value.clone());
assert_eq!(v, *value); assert_eq!(v, Ok(value));
// Make sure we can round trip back to `Value`. // Make sure we can round trip back to `Value`.
let json_value2: Value = from_value(json_value.clone()).unwrap(); let json_value2: Result<Value, Error> = from_value(json_value.clone());
assert_eq!(json_value, json_value2); assert_eq!(json_value2, Ok(json_value));
} }
} }
// FIXME (#5527): these could be merged once UFCS is finished. // FIXME (#5527): these could be merged once UFCS is finished.
fn test_parse_err<'a, T>(errors: &[(&'a str, Error)]) fn test_parse_err<T>(errors: Vec<(&'static str, Error)>)
where T: Debug + de::Deserialize, where T: Debug + PartialEq + de::Deserialize,
{ {
for &(s, ref err) in errors { for (s, err) in errors {
let v: Result<T, Error> = from_str(s); let v: Result<T, Error> = from_str(s);
assert_eq!(v.unwrap_err(), *err); assert_eq!(v, Err(err));
} }
} }
#[test] #[test]
fn test_parse_null() { fn test_parse_null() {
test_parse_err::<()>(&[ test_parse_err::<()>(vec![
("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)), ("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)), ("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)), ("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("null", ()), ("null", ()),
]); ]);
} }
#[test] #[test]
fn test_parse_bool() { fn test_parse_bool() {
test_parse_err::<bool>(&[ test_parse_err::<bool>(vec![
("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)), ("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)), ("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)), ("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
@ -683,7 +686,7 @@ fn test_parse_bool() {
("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)), ("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("true", true), ("true", true),
(" true ", true), (" true ", true),
("false", false), ("false", false),
@ -693,7 +696,7 @@ fn test_parse_bool() {
#[test] #[test]
fn test_parse_number_errors() { fn test_parse_number_errors() {
test_parse_err::<f64>(&[ test_parse_err::<f64>(vec![
("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)), ("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
(".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)), (".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), ("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
@ -707,7 +710,7 @@ fn test_parse_number_errors() {
#[test] #[test]
fn test_parse_i64() { fn test_parse_i64() {
test_parse_ok(&[ test_parse_ok(vec![
("3", 3), ("3", 3),
("-2", -2), ("-2", -2),
("-1234", -1234), ("-1234", -1234),
@ -717,7 +720,7 @@ fn test_parse_i64() {
#[test] #[test]
fn test_parse_f64() { fn test_parse_f64() {
test_parse_ok(&[ test_parse_ok(vec![
("3.0", 3.0f64), ("3.0", 3.0f64),
("3.1", 3.1), ("3.1", 3.1),
("-1.2", -1.2), ("-1.2", -1.2),
@ -731,13 +734,13 @@ fn test_parse_f64() {
#[test] #[test]
fn test_parse_string() { fn test_parse_string() {
test_parse_err::<String>(&[ test_parse_err::<String>(vec![
("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)), ("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)),
("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)), ("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)),
("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)), ("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("\"\"", "".to_string()), ("\"\"", "".to_string()),
("\"foo\"", "foo".to_string()), ("\"foo\"", "foo".to_string()),
(" \"foo\" ", "foo".to_string()), (" \"foo\" ", "foo".to_string()),
@ -753,7 +756,7 @@ fn test_parse_string() {
#[test] #[test]
fn test_parse_list() { fn test_parse_list() {
test_parse_err::<Vec<f64>>(&[ test_parse_err::<Vec<f64>>(vec![
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)), ("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)), ("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 3)), ("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 3)),
@ -763,39 +766,39 @@ fn test_parse_list() {
("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)), ("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("[]", vec![]), ("[]", vec![]),
("[ ]", vec![]), ("[ ]", vec![]),
("[null]", vec![()]), ("[null]", vec![()]),
(" [ null ] ", vec![()]), (" [ null ] ", vec![()]),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("[true]", vec![true]), ("[true]", vec![true]),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("[3,1]", vec![3, 1]), ("[3,1]", vec![3, 1]),
(" [ 3 , 1 ] ", vec![3, 1]), (" [ 3 , 1 ] ", vec![3, 1]),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("[[3], [1, 2]]", vec![vec![3], vec![1, 2]]), ("[[3], [1, 2]]", vec![vec![3], vec![1, 2]]),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("[1]", (1,)), ("[1]", (1,)),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("[1, 2]", (1, 2)), ("[1, 2]", (1, 2)),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("[1, 2, 3]", (1, 2, 3)), ("[1, 2, 3]", (1, 2, 3)),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("[1, [2, 3]]", (1, (2, 3))), ("[1, [2, 3]]", (1, (2, 3))),
]); ]);
@ -805,7 +808,7 @@ fn test_parse_list() {
#[test] #[test]
fn test_parse_object() { fn test_parse_object() {
test_parse_err::<BTreeMap<String, u32>>(&[ test_parse_err::<BTreeMap<String, u32>>(vec![
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)), ("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)), ("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)), ("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)),
@ -820,7 +823,7 @@ fn test_parse_object() {
("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)), ("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
("{}", treemap!()), ("{}", treemap!()),
("{ }", treemap!()), ("{ }", treemap!()),
( (
@ -841,7 +844,7 @@ fn test_parse_object() {
), ),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
( (
"{\"a\": {\"b\": 3, \"c\": 4}}", "{\"a\": {\"b\": 3, \"c\": 4}}",
treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)), treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)),
@ -851,13 +854,13 @@ fn test_parse_object() {
#[test] #[test]
fn test_parse_struct() { fn test_parse_struct() {
test_parse_err::<Outer>(&[ test_parse_err::<Outer>(vec![
("[]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)), ("[]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)), ("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)), ("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
( (
"{ "{
\"inner\": [] \"inner\": []
@ -883,12 +886,12 @@ fn test_parse_struct() {
#[test] #[test]
fn test_parse_option() { fn test_parse_option() {
test_parse_ok(&[ test_parse_ok(vec![
("null", None::<String>), ("null", None::<String>),
("\"jodhpurs\"", Some("jodhpurs".to_string())), ("\"jodhpurs\"", Some("jodhpurs".to_string())),
]); ]);
#[derive(PartialEq, Debug)] #[derive(Clone, Debug, PartialEq)]
#[derive_serialize] #[derive_serialize]
#[derive_deserialize] #[derive_deserialize]
struct Foo { struct Foo {
@ -898,23 +901,28 @@ fn test_parse_option() {
let value: Foo = from_str("{}").unwrap(); let value: Foo = from_str("{}").unwrap();
assert_eq!(value, Foo { x: None }); assert_eq!(value, Foo { x: None });
test_parse_ok(&[ test_parse_ok(vec![
("{\"x\": null}", Foo { x: None }), ("{\"x\": null}", Foo { x: None }),
("{\"x\": 5}", Foo { x: Some(5) }), ("{\"x\": 5}", Foo { x: Some(5) }),
]); ]);
} }
#[test] #[test]
fn test_parse_enum() { fn test_parse_enum_errors() {
test_parse_err::<Animal>(&[ test_parse_err::<Animal>(vec![
("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)), ("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
("{\"Dog\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)),
("{\"Dog\":}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)), ("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)), ("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)), ("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)), ("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
]); ]);
}
test_parse_ok(&[ #[test]
fn test_parse_enum() {
test_parse_ok(vec![
("{\"Dog\":[]}", Animal::Dog), ("{\"Dog\":[]}", Animal::Dog),
(" { \"Dog\" : [ ] } ", Animal::Dog), (" { \"Dog\" : [ ] } ", Animal::Dog),
( (
@ -935,7 +943,7 @@ fn test_parse_enum() {
), ),
]); ]);
test_parse_ok(&[ test_parse_ok(vec![
( (
concat!( concat!(
"{", "{",
@ -953,7 +961,7 @@ fn test_parse_enum() {
#[test] #[test]
fn test_parse_trailing_whitespace() { fn test_parse_trailing_whitespace() {
test_parse_ok(&[ test_parse_ok(vec![
("[1, 2] ", vec![1, 2]), ("[1, 2] ", vec![1, 2]),
("[1, 2]\n", vec![1, 2]), ("[1, 2]\n", vec![1, 2]),
("[1, 2]\t", vec![1, 2]), ("[1, 2]\t", vec![1, 2]),
@ -963,7 +971,7 @@ fn test_parse_trailing_whitespace() {
#[test] #[test]
fn test_multiline_errors() { fn test_multiline_errors() {
test_parse_err::<BTreeMap<String, String>>(&[ test_parse_err::<BTreeMap<String, String>>(vec![
("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 8)), ("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 8)),
]); ]);
} }