Simplify the variant deserializer visitor
This commit is contained in:
parent
78137ee3a4
commit
eb4af09456
@ -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())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
src/de.rs
34
src/de.rs
@ -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 = ();
|
||||||
|
@ -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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user