mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 13:41:01 +00:00
deserialize tuple enums with single element directly as the value instead of a sequence
This commit is contained in:
committed by
Oliver Schneider
parent
447d08bd91
commit
5885111863
@@ -571,6 +571,11 @@ pub trait VariantVisitor {
|
|||||||
Err(Error::syntax_error())
|
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.
|
/// `visit_seq` is called when deserializing a tuple-like variant.
|
||||||
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
|
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor
|
where V: Visitor
|
||||||
@@ -601,6 +606,10 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
|
|||||||
(**self).visit_unit()
|
(**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>
|
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -555,6 +555,12 @@ fn deserialize_variant(
|
|||||||
Ok($type_ident::$variant_ident)
|
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) => {
|
ast::TupleVariantKind(ref args) => {
|
||||||
deserialize_tuple_variant(
|
deserialize_tuple_variant(
|
||||||
cx,
|
cx,
|
||||||
|
|||||||
@@ -632,20 +632,22 @@ impl<Iter> de::VariantVisitor for Deserializer<Iter>
|
|||||||
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
|
||||||
{
|
{
|
||||||
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> {
|
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)
|
de::Deserialize::deserialize(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
|
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: de::Visitor,
|
where V: de::Visitor,
|
||||||
{
|
{
|
||||||
try!(self.parse_object_colon());
|
|
||||||
|
|
||||||
de::Deserializer::visit(self, visitor)
|
de::Deserializer::visit(self, visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,8 +656,6 @@ impl<Iter> de::VariantVisitor for Deserializer<Iter>
|
|||||||
visitor: V) -> Result<V::Value, Error>
|
visitor: V) -> Result<V::Value, Error>
|
||||||
where V: de::Visitor,
|
where V: de::Visitor,
|
||||||
{
|
{
|
||||||
try!(self.parse_object_colon());
|
|
||||||
|
|
||||||
de::Deserializer::visit(self, visitor)
|
de::Deserializer::visit(self, visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+70
-81
@@ -687,33 +687,19 @@ impl de::Deserializer for Deserializer {
|
|||||||
|
|
||||||
let mut iter = value.into_iter();
|
let mut iter = value.into_iter();
|
||||||
|
|
||||||
let value = match iter.next() {
|
let (variant, value) = match iter.next() {
|
||||||
Some((variant, Value::Array(fields))) => {
|
Some(v) => v,
|
||||||
self.value = Some(Value::String(variant));
|
None => return Err(de::Error::syntax_error()),
|
||||||
|
|
||||||
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()); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// enums are encoded in json as maps with a single key:value pair
|
||||||
match iter.next() {
|
match iter.next() {
|
||||||
Some(_) => Err(de::Error::syntax_error()),
|
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> {
|
struct SeqDeserializer<'a> {
|
||||||
de: &'a mut Deserializer,
|
de: &'a mut Deserializer,
|
||||||
iter: vec::IntoIter<Value>,
|
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> {
|
struct MapDeserializer<'a> {
|
||||||
de: &'a mut Deserializer,
|
de: &'a mut Deserializer,
|
||||||
iter: btree_map::IntoIter<String, Value>,
|
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`
|
/// 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
|
||||||
|
|||||||
Reference in New Issue
Block a user