Support deserializing flattened untagged enum
This commit is contained in:
parent
f9c6f0ab62
commit
368961e961
@ -1132,18 +1132,6 @@ pub trait Deserializer<'de>: Sized {
|
|||||||
fn is_human_readable(&self) -> bool {
|
fn is_human_readable(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not public API.
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn private_deserialize_internally_tagged_enum<V>(
|
|
||||||
self,
|
|
||||||
visitor: V,
|
|
||||||
) -> Result<V::Value, Self::Error>
|
|
||||||
where
|
|
||||||
V: Visitor<'de>,
|
|
||||||
{
|
|
||||||
self.deserialize_any(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -2640,6 +2640,32 @@ pub struct FlatMapDeserializer<'a, 'de: 'a, E>(
|
|||||||
pub PhantomData<E>,
|
pub PhantomData<E>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
impl<'a, 'de, E> FlatMapDeserializer<'a, 'de, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
fn deserialize_other<V>(self, _: V) -> Result<V::Value, E>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
Err(Error::custom("can only flatten structs and maps"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_to_deserialize_other {
|
||||||
|
($($func:ident ( $($arg:ty),* ))*) => {
|
||||||
|
$(
|
||||||
|
fn $func<V>(self, $(_: $arg,)* visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
self.deserialize_other(visitor)
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E>
|
impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E>
|
||||||
where
|
where
|
||||||
@ -2647,11 +2673,15 @@ where
|
|||||||
{
|
{
|
||||||
type Error = E;
|
type Error = E;
|
||||||
|
|
||||||
fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
Err(Error::custom("can only flatten structs and maps"))
|
visitor.visit_map(FlatInternallyTaggedAccess {
|
||||||
|
iter: self.0.iter_mut(),
|
||||||
|
pending: None,
|
||||||
|
_marker: PhantomData,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_enum<V>(
|
fn deserialize_enum<V>(
|
||||||
@ -2710,24 +2740,31 @@ where
|
|||||||
visitor.visit_newtype_struct(self)
|
visitor.visit_newtype_struct(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
forward_to_deserialize_any! {
|
forward_to_deserialize_other! {
|
||||||
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
|
deserialize_bool()
|
||||||
byte_buf option unit unit_struct seq tuple tuple_struct identifier
|
deserialize_i8()
|
||||||
ignored_any
|
deserialize_i16()
|
||||||
}
|
deserialize_i32()
|
||||||
|
deserialize_i64()
|
||||||
fn private_deserialize_internally_tagged_enum<V>(
|
deserialize_u8()
|
||||||
self,
|
deserialize_u16()
|
||||||
visitor: V,
|
deserialize_u32()
|
||||||
) -> Result<V::Value, Self::Error>
|
deserialize_u64()
|
||||||
where
|
deserialize_f32()
|
||||||
V: Visitor<'de>,
|
deserialize_f64()
|
||||||
{
|
deserialize_char()
|
||||||
visitor.visit_map(FlatInternallyTaggedAccess {
|
deserialize_str()
|
||||||
iter: self.0.iter_mut(),
|
deserialize_string()
|
||||||
pending: None,
|
deserialize_bytes()
|
||||||
_marker: PhantomData,
|
deserialize_byte_buf()
|
||||||
})
|
deserialize_option()
|
||||||
|
deserialize_unit()
|
||||||
|
deserialize_unit_struct(&'static str)
|
||||||
|
deserialize_seq()
|
||||||
|
deserialize_tuple(usize)
|
||||||
|
deserialize_tuple_struct(&'static str, usize)
|
||||||
|
deserialize_identifier()
|
||||||
|
deserialize_ignored_any()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1263,7 +1263,7 @@ fn deserialize_internally_tagged_enum(
|
|||||||
|
|
||||||
#variants_stmt
|
#variants_stmt
|
||||||
|
|
||||||
let __tagged = try!(_serde::Deserializer::private_deserialize_internally_tagged_enum(
|
let __tagged = try!(_serde::Deserializer::deserialize_any(
|
||||||
__deserializer,
|
__deserializer,
|
||||||
_serde::private::de::TaggedContentVisitor::<__Field>::new(#tag)));
|
_serde::private::de::TaggedContentVisitor::<__Field>::new(#tag)));
|
||||||
|
|
||||||
|
@ -2062,3 +2062,36 @@ fn test_untagged_enum_containing_flatten() {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_flatten_untagged_enum() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Outer {
|
||||||
|
#[serde(flatten)]
|
||||||
|
inner: Inner,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum Inner {
|
||||||
|
Variant {
|
||||||
|
a: i32,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = Outer {
|
||||||
|
inner: Inner::Variant {
|
||||||
|
a: 0,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&data,
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user