deserialize tuple enums with single element directly as the value instead of a sequence

This commit is contained in:
Oliver Schneider 2015-07-14 11:12:01 +02:00 committed by Oliver Schneider
parent 447d08bd91
commit 5885111863
4 changed files with 91 additions and 87 deletions

View File

@ -571,6 +571,11 @@ pub trait VariantVisitor {
Err(Error::syntax_error())
}
/// `visit_simple` is called when deserializing a variant with a single value.
fn visit_simple<T: Deserialize>(&mut self) -> Result<T, Self::Error> {
Err(Error::syntax_error())
}
/// `visit_seq` is called when deserializing a tuple-like variant.
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor
@ -601,6 +606,10 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
(**self).visit_unit()
}
fn visit_simple<D: Deserialize>(&mut self) -> Result<D, T::Error> {
(**self).visit_simple()
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{

View File

@ -555,6 +555,12 @@ fn deserialize_variant(
Ok($type_ident::$variant_ident)
})
}
ast::TupleVariantKind(ref args) if args.len() == 1 => {
quote_expr!(cx, {
let val = try!(visitor.visit_simple());
Ok($type_ident::$variant_ident(val))
})
}
ast::TupleVariantKind(ref args) => {
deserialize_tuple_variant(
cx,

View File

@ -632,20 +632,22 @@ impl<Iter> de::VariantVisitor for Deserializer<Iter>
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize
{
de::Deserialize::deserialize(self)
let val = try!(de::Deserialize::deserialize(self));
try!(self.parse_object_colon());
Ok(val)
}
fn visit_unit(&mut self) -> Result<(), Error> {
try!(self.parse_object_colon());
de::Deserialize::deserialize(self)
}
fn visit_simple<T: de::Deserialize>(&mut self) -> Result<T, Error> {
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
try!(self.parse_object_colon());
de::Deserializer::visit(self, visitor)
}
@ -654,8 +656,6 @@ impl<Iter> de::VariantVisitor for Deserializer<Iter>
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
try!(self.parse_object_colon());
de::Deserializer::visit(self, visitor)
}
}

View File

@ -687,33 +687,19 @@ impl de::Deserializer for Deserializer {
let mut iter = value.into_iter();
let value = match iter.next() {
Some((variant, Value::Array(fields))) => {
self.value = Some(Value::String(variant));
let len = fields.len();
try!(visitor.visit(SeqDeserializer {
de: self,
iter: fields.into_iter(),
len: len,
}))
}
Some((variant, Value::Object(fields))) => {
let len = fields.len();
try!(visitor.visit(MapDeserializer {
de: self,
iter: fields.into_iter(),
value: Some(Value::String(variant)),
len: len,
}))
}
Some(_) => { return Err(de::Error::syntax_error()); }
None => { return Err(de::Error::syntax_error()); }
let (variant, value) = match iter.next() {
Some(v) => v,
None => return Err(de::Error::syntax_error()),
};
// enums are encoded in json as maps with a single key:value pair
match iter.next() {
Some(_) => Err(de::Error::syntax_error()),
None => Ok(value)
None => visitor.visit(VariantDeserializer {
de: self,
val: Some(value),
variant: Some(Value::String(variant)),
}),
}
}
@ -723,6 +709,67 @@ impl de::Deserializer for Deserializer {
}
}
struct VariantDeserializer<'a> {
de: &'a mut Deserializer,
val: Option<Value>,
variant: Option<Value>,
}
impl<'a> de::VariantVisitor for VariantDeserializer<'a> {
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
de::Deserialize::deserialize(&mut Deserializer::new(self.variant.take().unwrap()))
}
fn visit_unit(&mut self) -> Result<(), Error>
{
de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap()))
}
fn visit_simple<D: de::Deserialize>(&mut self) -> Result<D, Error>
{
de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap()))
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
if let Value::Array(fields) = self.val.take().unwrap() {
de::Deserializer::visit(
&mut SeqDeserializer {
de: self.de,
len: fields.len(),
iter: fields.into_iter(),
},
visitor,
)
} else {
Err(de::Error::syntax_error())
}
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
if let Value::Object(fields) = self.val.take().unwrap() {
de::Deserializer::visit(
&mut MapDeserializer {
de: self.de,
len: fields.len(),
iter: fields.into_iter(),
value: None,
},
visitor,
)
} else {
Err(de::Error::syntax_error())
}
}
}
struct SeqDeserializer<'a> {
de: &'a mut Deserializer,
iter: vec::IntoIter<Value>,
@ -773,35 +820,6 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
}
}
impl<'a> de::VariantVisitor for SeqDeserializer<'a> {
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
de::Deserialize::deserialize(self.de)
}
fn visit_unit(&mut self) -> Result<(), Error>
{
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
}
struct MapDeserializer<'a> {
de: &'a mut Deserializer,
iter: btree_map::IntoIter<String, Value>,
@ -884,35 +902,6 @@ impl<'a> de::Deserializer for MapDeserializer<'a> {
}
}
impl<'a> de::VariantVisitor for MapDeserializer<'a> {
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
self.de.value = self.value.take();
de::Deserialize::deserialize(self.de)
}
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
}
/// Shortcut function to encode a `T` into a JSON `Value`
pub fn to_value<T>(value: &T) -> Value
where T: ser::Serialize