Add Deserializer::visit_enum to help json enum deserialization

This commit is contained in:
Erick Tryzelaar
2015-03-05 07:36:30 -08:00
parent 1b632cea9c
commit ddfaf9d177
5 changed files with 322 additions and 72 deletions
+80 -2
View File
@@ -36,6 +36,17 @@ pub trait Deserializer {
{
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 {
@@ -211,6 +222,8 @@ pub trait Visitor {
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait SeqVisitor {
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 {
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 {
type Error: Error;
@@ -276,6 +350,8 @@ pub trait EnumVisitor {
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumSeqVisitor {
type Value;
@@ -283,6 +359,8 @@ pub trait EnumSeqVisitor {
where V: SeqVisitor;
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumMapVisitor {
type Value;
@@ -374,12 +452,12 @@ impl<
> self::Visitor for PrimitiveVisitor<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!(i16, visit_i16, from_i16);
impl_deserialize_num_method!(i32, visit_i32, from_i32);
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!(u16, visit_u16, from_u16);
impl_deserialize_num_method!(u32, visit_u32, from_u32);
+114 -21
View File
@@ -104,17 +104,11 @@ impl<Iter: Iterator<Item=u8>> Deserializer<Iter> {
}
b'[' => {
self.bump();
visitor.visit_seq(SeqVisitor {
de: self,
first: true,
})
visitor.visit_seq(SeqVisitor::new(self))
}
b'{' => {
self.bump();
visitor.visit_map(MapVisitor {
de: self,
first: true,
})
visitor.visit_map(MapVisitor::new(self))
}
_ => {
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> {
@@ -396,6 +403,38 @@ impl<Iter: Iterator<Item=u8>> de::Deserializer for Deserializer<Iter> {
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> {
@@ -403,7 +442,18 @@ struct SeqVisitor<'a, Iter: 'a> {
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;
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> {
self.de.parse_whitespace();
if self.de.ch_is(b']') {
self.de.bump();
Ok(())
@@ -449,7 +501,18 @@ struct MapVisitor<'a, Iter: 'a> {
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;
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>
where V: de::Deserialize,
{
self.de.parse_whitespace();
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();
try!(self.de.parse_object_colon());
Ok(try!(de::Deserialize::deserialize(self.de)))
}
fn end(&mut self) -> Result<(), Error> {
self.de.parse_whitespace();
if self.de.ch_is(b']') {
self.de.bump();
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>`.
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
where I: Iterator<Item=u8>,
+90 -22
View File
@@ -46,11 +46,6 @@ impl de::Deserialize for Value {
impl de::Visitor for ValueVisitor {
type Value = Value;
#[inline]
fn visit_unit<E>(&mut self) -> Result<Value, E> {
Ok(Value::Null)
}
#[inline]
fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
Ok(Value::Bool(value))
@@ -90,6 +85,11 @@ impl de::Deserialize for Value {
de::Deserialize::deserialize(deserializer)
}
#[inline]
fn visit_unit<E>(&mut self) -> Result<Value, E> {
Ok(Value::Null)
}
#[inline]
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::SeqVisitor,
@@ -157,7 +157,7 @@ impl Serializer {
pub fn unwrap(mut self) -> Value {
match self.state.pop().unwrap() {
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)) { }
match self.state.pop().unwrap() {
State::Array(values) => {
self.state.push(State::Value(Value::Array(values)));
}
_ => panic!(),
}
let values = match self.state.pop().unwrap() {
State::Array(values) => values,
state => panic!("Expected array, found {:?}", state),
};
self.state.push(State::Value(Value::Array(values)));
Ok(())
}
@@ -276,7 +276,7 @@ impl ser::Visitor for Serializer {
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
_ => panic!(),
state => panic!("expected value, found {:?}", state),
};
let mut object = BTreeMap::new();
@@ -296,12 +296,12 @@ impl ser::Visitor for Serializer {
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
_ => panic!(),
state => panic!("expected value, found {:?}", state),
};
match *self.state.last_mut().unwrap() {
State::Array(ref mut values) => { values.push(value); }
_ => panic!(),
ref state => panic!("expected array, found {:?}", state),
}
Ok(())
@@ -317,12 +317,12 @@ impl ser::Visitor for Serializer {
while let Some(()) = try!(visitor.visit(self)) { }
match self.state.pop().unwrap() {
State::Object(values) => {
self.state.push(State::Value(Value::Object(values)));
}
_ => panic!(),
}
let values = match self.state.pop().unwrap() {
State::Object(values) => values,
state => panic!("expected object, found {:?}", state),
};
self.state.push(State::Value(Value::Object(values)));
Ok(())
}
@@ -335,7 +335,7 @@ impl ser::Visitor for Serializer {
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
_ => panic!(),
state => panic!("expected value, found {:?}", state),
};
let mut object = BTreeMap::new();
@@ -436,6 +436,46 @@ impl de::Deserializer for Deserializer {
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> {
@@ -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> {
de: &'a mut Deserializer,
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`
pub fn to_value<T>(value: &T) -> Value
where T: ser::Serialize