mirror of
https://github.com/serde-rs/serde.git
synced 2025-10-03 15:55:55 +00:00
Add Deserializer::visit_enum to help json enum deserialization
This commit is contained in:
parent
1b632cea9c
commit
ddfaf9d177
@ -1265,7 +1265,7 @@ fn deserialize_enum(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$state.visit(__Visitor)
|
$state.visit_enum(__Visitor)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,17 @@ pub trait Deserializer {
|
|||||||
{
|
{
|
||||||
self.visit(visitor)
|
self.visit(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The `visit_enum` method allows a `Deserialize` type to inform the
|
||||||
|
/// `Deserializer` that it's expecting an enum value. This allows
|
||||||
|
/// deserializers that provide a custom enumeration serialization to
|
||||||
|
/// properly deserialize the type.
|
||||||
|
#[inline]
|
||||||
|
fn visit_enum<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
self.visit(visitor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Visitor {
|
pub trait Visitor {
|
||||||
@ -211,6 +222,8 @@ pub trait Visitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub trait SeqVisitor {
|
pub trait SeqVisitor {
|
||||||
type Error: Error;
|
type Error: Error;
|
||||||
|
|
||||||
@ -225,6 +238,29 @@ pub trait SeqVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor {
|
||||||
|
type Error = V::Error;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit<T>(&mut self) -> Result<Option<T>, V::Error>
|
||||||
|
where T: Deserialize
|
||||||
|
{
|
||||||
|
(**self).visit()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn end(&mut self) -> Result<(), V::Error> {
|
||||||
|
(**self).end()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
(**self).size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub trait MapVisitor {
|
pub trait MapVisitor {
|
||||||
type Error: Error;
|
type Error: Error;
|
||||||
|
|
||||||
@ -256,6 +292,44 @@ pub trait MapVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
|
||||||
|
type Error = V_::Error;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, V_::Error>
|
||||||
|
where K: Deserialize,
|
||||||
|
V: Deserialize,
|
||||||
|
{
|
||||||
|
(**self).visit()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_key<K>(&mut self) -> Result<Option<K>, V_::Error>
|
||||||
|
where K: Deserialize
|
||||||
|
{
|
||||||
|
(**self).visit_key()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_value<V>(&mut self) -> Result<V, V_::Error>
|
||||||
|
where V: Deserialize
|
||||||
|
{
|
||||||
|
(**self).visit_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn end(&mut self) -> Result<(), V_::Error> {
|
||||||
|
(**self).end()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
(**self).size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub trait EnumVisitor {
|
pub trait EnumVisitor {
|
||||||
type Error: Error;
|
type Error: Error;
|
||||||
|
|
||||||
@ -276,6 +350,8 @@ pub trait EnumVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub trait EnumSeqVisitor {
|
pub trait EnumSeqVisitor {
|
||||||
type Value;
|
type Value;
|
||||||
|
|
||||||
@ -283,6 +359,8 @@ pub trait EnumSeqVisitor {
|
|||||||
where V: SeqVisitor;
|
where V: SeqVisitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub trait EnumMapVisitor {
|
pub trait EnumMapVisitor {
|
||||||
type Value;
|
type Value;
|
||||||
|
|
||||||
@ -374,12 +452,12 @@ impl<
|
|||||||
> self::Visitor for PrimitiveVisitor<T> {
|
> self::Visitor for PrimitiveVisitor<T> {
|
||||||
type Value = T;
|
type Value = T;
|
||||||
|
|
||||||
impl_deserialize_num_method!(isize, visit_isize, from_int);
|
impl_deserialize_num_method!(isize, visit_isize, from_isize);
|
||||||
impl_deserialize_num_method!(i8, visit_i8, from_i8);
|
impl_deserialize_num_method!(i8, visit_i8, from_i8);
|
||||||
impl_deserialize_num_method!(i16, visit_i16, from_i16);
|
impl_deserialize_num_method!(i16, visit_i16, from_i16);
|
||||||
impl_deserialize_num_method!(i32, visit_i32, from_i32);
|
impl_deserialize_num_method!(i32, visit_i32, from_i32);
|
||||||
impl_deserialize_num_method!(i64, visit_i64, from_i64);
|
impl_deserialize_num_method!(i64, visit_i64, from_i64);
|
||||||
impl_deserialize_num_method!(usize, visit_usize, from_uint);
|
impl_deserialize_num_method!(usize, visit_usize, from_usize);
|
||||||
impl_deserialize_num_method!(u8, visit_u8, from_u8);
|
impl_deserialize_num_method!(u8, visit_u8, from_u8);
|
||||||
impl_deserialize_num_method!(u16, visit_u16, from_u16);
|
impl_deserialize_num_method!(u16, visit_u16, from_u16);
|
||||||
impl_deserialize_num_method!(u32, visit_u32, from_u32);
|
impl_deserialize_num_method!(u32, visit_u32, from_u32);
|
||||||
|
@ -104,17 +104,11 @@ impl<Iter: Iterator<Item=u8>> Deserializer<Iter> {
|
|||||||
}
|
}
|
||||||
b'[' => {
|
b'[' => {
|
||||||
self.bump();
|
self.bump();
|
||||||
visitor.visit_seq(SeqVisitor {
|
visitor.visit_seq(SeqVisitor::new(self))
|
||||||
de: self,
|
|
||||||
first: true,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
b'{' => {
|
b'{' => {
|
||||||
self.bump();
|
self.bump();
|
||||||
visitor.visit_map(MapVisitor {
|
visitor.visit_map(MapVisitor::new(self))
|
||||||
de: self,
|
|
||||||
first: true,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
Err(self.error(ErrorCode::ExpectedSomeValue))
|
Err(self.error(ErrorCode::ExpectedSomeValue))
|
||||||
@ -367,6 +361,19 @@ impl<Iter: Iterator<Item=u8>> Deserializer<Iter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_object_colon(&mut self) -> Result<(), Error> {
|
||||||
|
self.parse_whitespace();
|
||||||
|
|
||||||
|
if self.ch_is(b':') {
|
||||||
|
self.bump();
|
||||||
|
Ok(())
|
||||||
|
} else if self.eof() {
|
||||||
|
Err(self.error(ErrorCode::EOFWhileParsingObject))
|
||||||
|
} else {
|
||||||
|
Err(self.error(ErrorCode::ExpectedColon))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Iter: Iterator<Item=u8>> de::Deserializer for Deserializer<Iter> {
|
impl<Iter: Iterator<Item=u8>> de::Deserializer for Deserializer<Iter> {
|
||||||
@ -396,6 +403,38 @@ impl<Iter: Iterator<Item=u8>> de::Deserializer for Deserializer<Iter> {
|
|||||||
visitor.visit_some(self)
|
visitor.visit_some(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
|
self.parse_whitespace();
|
||||||
|
|
||||||
|
if self.ch_is(b'{') {
|
||||||
|
self.bump();
|
||||||
|
self.parse_whitespace();
|
||||||
|
|
||||||
|
try!(self.parse_string());
|
||||||
|
try!(self.parse_object_colon());
|
||||||
|
|
||||||
|
let variant = str::from_utf8(&self.buf).unwrap().to_string();
|
||||||
|
|
||||||
|
let value = try!(visitor.visit_variant(&variant, EnumVisitor {
|
||||||
|
de: self,
|
||||||
|
}));
|
||||||
|
|
||||||
|
self.parse_whitespace();
|
||||||
|
|
||||||
|
if self.ch_is(b'}') {
|
||||||
|
self.bump();
|
||||||
|
Ok(value)
|
||||||
|
} else {
|
||||||
|
return Err(self.error(ErrorCode::ExpectedSomeValue));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(self.error(ErrorCode::ExpectedSomeValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SeqVisitor<'a, Iter: 'a> {
|
struct SeqVisitor<'a, Iter: 'a> {
|
||||||
@ -403,7 +442,18 @@ struct SeqVisitor<'a, Iter: 'a> {
|
|||||||
first: bool,
|
first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Iter: Iterator<Item=u8>> de::SeqVisitor for SeqVisitor<'a, Iter> {
|
impl<'a, Iter> SeqVisitor<'a, Iter> {
|
||||||
|
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||||
|
SeqVisitor {
|
||||||
|
de: de,
|
||||||
|
first: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
|
||||||
|
where Iter: Iterator<Item=u8>
|
||||||
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||||
@ -433,6 +483,8 @@ impl<'a, Iter: Iterator<Item=u8>> de::SeqVisitor for SeqVisitor<'a, Iter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
fn end(&mut self) -> Result<(), Error> {
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
|
||||||
if self.de.ch_is(b']') {
|
if self.de.ch_is(b']') {
|
||||||
self.de.bump();
|
self.de.bump();
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -449,7 +501,18 @@ struct MapVisitor<'a, Iter: 'a> {
|
|||||||
first: bool,
|
first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Iter: Iterator<Item=u8>> de::MapVisitor for MapVisitor<'a, Iter> {
|
impl<'a, Iter> MapVisitor<'a, Iter> {
|
||||||
|
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||||
|
MapVisitor {
|
||||||
|
de: de,
|
||||||
|
first: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
|
||||||
|
where Iter: Iterator<Item=u8>
|
||||||
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||||
@ -489,22 +552,14 @@ impl<'a, Iter: Iterator<Item=u8>> de::MapVisitor for MapVisitor<'a, Iter> {
|
|||||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||||
where V: de::Deserialize,
|
where V: de::Deserialize,
|
||||||
{
|
{
|
||||||
self.de.parse_whitespace();
|
try!(self.de.parse_object_colon());
|
||||||
|
|
||||||
if self.de.ch_is(b':') {
|
|
||||||
self.de.bump();
|
|
||||||
} else if self.de.eof() {
|
|
||||||
return Err(self.de.error(ErrorCode::EOFWhileParsingObject));
|
|
||||||
} else {
|
|
||||||
return Err(self.de.error(ErrorCode::ExpectedColon));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.de.parse_whitespace();
|
|
||||||
|
|
||||||
Ok(try!(de::Deserialize::deserialize(self.de)))
|
Ok(try!(de::Deserialize::deserialize(self.de)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
fn end(&mut self) -> Result<(), Error> {
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
|
||||||
if self.de.ch_is(b']') {
|
if self.de.ch_is(b']') {
|
||||||
self.de.bump();
|
self.de.bump();
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -516,6 +571,44 @@ impl<'a, Iter: Iterator<Item=u8>> de::MapVisitor for MapVisitor<'a, Iter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct EnumVisitor<'a, Iter: 'a> {
|
||||||
|
de: &'a mut Deserializer<Iter>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Iter: Iterator<Item=u8>> de::EnumVisitor for EnumVisitor<'a, Iter> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit_unit(&mut self) -> Result<(), Error> {
|
||||||
|
de::Deserialize::deserialize(self.de)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::EnumSeqVisitor,
|
||||||
|
{
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
|
||||||
|
if self.de.ch_is(b'[') {
|
||||||
|
self.de.bump();
|
||||||
|
visitor.visit(SeqVisitor::new(self.de))
|
||||||
|
} else {
|
||||||
|
Err(self.de.error(ErrorCode::ExpectedSomeValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::EnumMapVisitor,
|
||||||
|
{
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
|
||||||
|
if self.de.ch_is(b'{') {
|
||||||
|
self.de.bump();
|
||||||
|
visitor.visit(MapVisitor::new(self.de))
|
||||||
|
} else {
|
||||||
|
Err(self.de.error(ErrorCode::ExpectedSomeValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Decodes a json value from an `Iterator<u8>`.
|
/// Decodes a json value from an `Iterator<u8>`.
|
||||||
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
|
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
|
||||||
where I: Iterator<Item=u8>,
|
where I: Iterator<Item=u8>,
|
||||||
|
@ -46,11 +46,6 @@ impl de::Deserialize for Value {
|
|||||||
impl de::Visitor for ValueVisitor {
|
impl de::Visitor for ValueVisitor {
|
||||||
type Value = Value;
|
type Value = Value;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_unit<E>(&mut self) -> Result<Value, E> {
|
|
||||||
Ok(Value::Null)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
|
fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
|
||||||
Ok(Value::Bool(value))
|
Ok(Value::Bool(value))
|
||||||
@ -90,6 +85,11 @@ impl de::Deserialize for Value {
|
|||||||
de::Deserialize::deserialize(deserializer)
|
de::Deserialize::deserialize(deserializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_unit<E>(&mut self) -> Result<Value, E> {
|
||||||
|
Ok(Value::Null)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
|
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
|
||||||
where V: de::SeqVisitor,
|
where V: de::SeqVisitor,
|
||||||
@ -157,7 +157,7 @@ impl Serializer {
|
|||||||
pub fn unwrap(mut self) -> Value {
|
pub fn unwrap(mut self) -> Value {
|
||||||
match self.state.pop().unwrap() {
|
match self.state.pop().unwrap() {
|
||||||
State::Value(value) => value,
|
State::Value(value) => value,
|
||||||
_ => panic!(),
|
state => panic!("expected value, found {:?}", state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,12 +258,12 @@ impl ser::Visitor for Serializer {
|
|||||||
|
|
||||||
while let Some(()) = try!(visitor.visit(self)) { }
|
while let Some(()) = try!(visitor.visit(self)) { }
|
||||||
|
|
||||||
match self.state.pop().unwrap() {
|
let values = match self.state.pop().unwrap() {
|
||||||
State::Array(values) => {
|
State::Array(values) => values,
|
||||||
|
state => panic!("Expected array, found {:?}", state),
|
||||||
|
};
|
||||||
|
|
||||||
self.state.push(State::Value(Value::Array(values)));
|
self.state.push(State::Value(Value::Array(values)));
|
||||||
}
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -276,7 +276,7 @@ impl ser::Visitor for Serializer {
|
|||||||
|
|
||||||
let value = match self.state.pop().unwrap() {
|
let value = match self.state.pop().unwrap() {
|
||||||
State::Value(value) => value,
|
State::Value(value) => value,
|
||||||
_ => panic!(),
|
state => panic!("expected value, found {:?}", state),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut object = BTreeMap::new();
|
let mut object = BTreeMap::new();
|
||||||
@ -296,12 +296,12 @@ impl ser::Visitor for Serializer {
|
|||||||
|
|
||||||
let value = match self.state.pop().unwrap() {
|
let value = match self.state.pop().unwrap() {
|
||||||
State::Value(value) => value,
|
State::Value(value) => value,
|
||||||
_ => panic!(),
|
state => panic!("expected value, found {:?}", state),
|
||||||
};
|
};
|
||||||
|
|
||||||
match *self.state.last_mut().unwrap() {
|
match *self.state.last_mut().unwrap() {
|
||||||
State::Array(ref mut values) => { values.push(value); }
|
State::Array(ref mut values) => { values.push(value); }
|
||||||
_ => panic!(),
|
ref state => panic!("expected array, found {:?}", state),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -317,12 +317,12 @@ impl ser::Visitor for Serializer {
|
|||||||
|
|
||||||
while let Some(()) = try!(visitor.visit(self)) { }
|
while let Some(()) = try!(visitor.visit(self)) { }
|
||||||
|
|
||||||
match self.state.pop().unwrap() {
|
let values = match self.state.pop().unwrap() {
|
||||||
State::Object(values) => {
|
State::Object(values) => values,
|
||||||
|
state => panic!("expected object, found {:?}", state),
|
||||||
|
};
|
||||||
|
|
||||||
self.state.push(State::Value(Value::Object(values)));
|
self.state.push(State::Value(Value::Object(values)));
|
||||||
}
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -335,7 +335,7 @@ impl ser::Visitor for Serializer {
|
|||||||
|
|
||||||
let value = match self.state.pop().unwrap() {
|
let value = match self.state.pop().unwrap() {
|
||||||
State::Value(value) => value,
|
State::Value(value) => value,
|
||||||
_ => panic!(),
|
state => panic!("expected value, found {:?}", state),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut object = BTreeMap::new();
|
let mut object = BTreeMap::new();
|
||||||
@ -436,6 +436,46 @@ impl de::Deserializer for Deserializer {
|
|||||||
None => Err(de::Error::end_of_stream_error()),
|
None => Err(de::Error::end_of_stream_error()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
|
let value = match self.value.take() {
|
||||||
|
Some(Value::Object(value)) => value,
|
||||||
|
Some(_) => { return Err(de::Error::syntax_error()); }
|
||||||
|
None => { return Err(de::Error::end_of_stream_error()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut iter = value.into_iter();
|
||||||
|
|
||||||
|
let value = match iter.next() {
|
||||||
|
Some((variant, Value::Array(fields))) => {
|
||||||
|
let len = fields.len();
|
||||||
|
try!(visitor.visit_variant(&variant, SeqDeserializer {
|
||||||
|
de: self,
|
||||||
|
iter: fields.into_iter(),
|
||||||
|
len: len,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Some((variant, Value::Object(fields))) => {
|
||||||
|
let len = fields.len();
|
||||||
|
try!(visitor.visit_variant(&variant, MapDeserializer {
|
||||||
|
de: self,
|
||||||
|
iter: fields.into_iter(),
|
||||||
|
value: None,
|
||||||
|
len: len,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Some(_) => { return Err(de::Error::syntax_error()); }
|
||||||
|
None => { return Err(de::Error::syntax_error()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
match iter.next() {
|
||||||
|
Some(_) => Err(de::Error::syntax_error()),
|
||||||
|
None => Ok(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SeqDeserializer<'a> {
|
struct SeqDeserializer<'a> {
|
||||||
@ -473,6 +513,24 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> de::EnumVisitor for SeqDeserializer<'a> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit_unit(&mut self) -> Result<(), Error> {
|
||||||
|
if self.len == 0 {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct MapDeserializer<'a> {
|
struct MapDeserializer<'a> {
|
||||||
de: &'a mut Deserializer,
|
de: &'a mut Deserializer,
|
||||||
iter: btree_map::IntoIter<String, Value>,
|
iter: btree_map::IntoIter<String, Value>,
|
||||||
@ -518,6 +576,16 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> de::EnumVisitor for MapDeserializer<'a> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::EnumMapVisitor,
|
||||||
|
{
|
||||||
|
visitor.visit(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Shortcut function to encode a `T` into a JSON `Value`
|
/// Shortcut function to encode a `T` into a JSON `Value`
|
||||||
pub fn to_value<T>(value: &T) -> Value
|
pub fn to_value<T>(value: &T) -> Value
|
||||||
where T: ser::Serialize
|
where T: ser::Serialize
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![feature(io, plugin, test)]
|
#![feature(plugin, test)]
|
||||||
#![plugin(serde2_macros)]
|
#![plugin(serde2_macros)]
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
@ -13,9 +13,7 @@ use serde2::ser;
|
|||||||
|
|
||||||
use serde2::json::{
|
use serde2::json::{
|
||||||
self,
|
self,
|
||||||
Deserializer,
|
|
||||||
Error,
|
Error,
|
||||||
Serializer,
|
|
||||||
Value,
|
Value,
|
||||||
from_str,
|
from_str,
|
||||||
from_value,
|
from_value,
|
||||||
@ -556,19 +554,17 @@ fn test_parse_f64() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_string_errors() {
|
fn test_parse_string() {
|
||||||
test_parse_err::<string::String>(&[
|
test_parse_err::<string::String>(&[
|
||||||
("\"", SyntaxError(EOFWhileParsingString, 1, 2)),
|
("\"", SyntaxError(EOFWhileParsingString, 1, 2)),
|
||||||
("\"lol", SyntaxError(EOFWhileParsingString, 1, 5)),
|
("\"lol", SyntaxError(EOFWhileParsingString, 1, 5)),
|
||||||
("\"lol\"a", SyntaxError(TrailingCharacters, 1, 6)),
|
("\"lol\"a", SyntaxError(TrailingCharacters, 1, 6)),
|
||||||
]);
|
]);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_string() {
|
|
||||||
test_parse_ok(&[
|
test_parse_ok(&[
|
||||||
("\"\"", "".to_string()),
|
("\"\"", "".to_string()),
|
||||||
("\"foo\"", "foo".to_string()),
|
("\"foo\"", "foo".to_string()),
|
||||||
|
(" \"foo\" ", "foo".to_string()),
|
||||||
("\"\\\"\"", "\"".to_string()),
|
("\"\\\"\"", "\"".to_string()),
|
||||||
("\"\\b\"", "\x08".to_string()),
|
("\"\\b\"", "\x08".to_string()),
|
||||||
("\"\\n\"", "\n".to_string()),
|
("\"\\n\"", "\n".to_string()),
|
||||||
@ -716,25 +712,47 @@ fn test_parse_option() {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_enum() {
|
fn test_parse_enum() {
|
||||||
|
/*
|
||||||
|
test_parse_err::<Animal>(&[
|
||||||
|
("{", SyntaxError(EOFWhileParsingString, 1, 2)),
|
||||||
|
("{ ", SyntaxError(EOFWhileParsingString, 1, 3)),
|
||||||
|
("{1", SyntaxError(KeyMustBeAString, 1, 2)),
|
||||||
|
("{ \"a\"", SyntaxError(EOFWhileParsingObject, 1, 6)),
|
||||||
|
("{\"a\"", SyntaxError(EOFWhileParsingObject, 1, 5)),
|
||||||
|
("{\"a\" ", SyntaxError(EOFWhileParsingObject, 1, 6)),
|
||||||
|
("{\"a\" 1", SyntaxError(ExpectedColon, 1, 6)),
|
||||||
|
("{\"a\":", SyntaxError(EOFWhileParsingValue, 1, 6)),
|
||||||
|
("{\"a\":1", SyntaxError(EOFWhileParsingObject, 1, 7)),
|
||||||
|
("{\"a\":1 1", SyntaxError(ExpectedObjectCommaOrEnd, 1, 8)),
|
||||||
|
("{\"a\":1,", SyntaxError(EOFWhileParsingValue, 1, 8)),
|
||||||
|
("{}a", SyntaxError(TrailingCharacters, 1, 3)),
|
||||||
|
]);
|
||||||
|
*/
|
||||||
|
|
||||||
test_parse_ok(&[
|
test_parse_ok(&[
|
||||||
|
("{\"Dog\":[]}", Animal::Dog),
|
||||||
(" { \"Dog\" : [ ] } ", Animal::Dog),
|
(" { \"Dog\" : [ ] } ", Animal::Dog),
|
||||||
(
|
(
|
||||||
"{\"Frog\":[\"Henry\",[]]}",
|
"{\"Frog\":[\"Henry\",[]]}",
|
||||||
Animal::Frog("Henry".to_string(), vec!()),
|
Animal::Frog("Henry".to_string(), vec!()),
|
||||||
),
|
),
|
||||||
(
|
|
||||||
"{\"Frog\": [\"Henry\", [349]]}",
|
|
||||||
Animal::Frog("Henry".to_string(), vec!(349)),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
" { \"Frog\": [ \"Henry\" , [ 349, 102 ] ] } ",
|
" { \"Frog\": [ \"Henry\" , [ 349, 102 ] ] } ",
|
||||||
Animal::Frog("Henry".to_string(), vec!(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(&[
|
test_parse_ok(&[
|
||||||
(
|
(
|
||||||
concat!(
|
concat!(
|
||||||
@ -749,17 +767,10 @@ fn test_parse_enum() {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
/*
|
||||||
fn test_json_deserialize_enum() {
|
|
||||||
test_json_deserialize_ok(&[
|
|
||||||
Animal::Dog,
|
|
||||||
Animal::Frog("Henry".to_string(), vec!()),
|
|
||||||
Animal::Frog("Henry".to_string(), vec!(349)),
|
|
||||||
Animal::Frog("Henry".to_string(), vec!(349, 102)),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_multiline_errors() {
|
fn test_multiline_errors() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user