Merge pull request #1559 from dtolnay/ignore-enum
Accept enums in IgnoredAny
This commit is contained in:
commit
abd3fd004e
@ -1,6 +1,8 @@
|
||||
use lib::*;
|
||||
|
||||
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
||||
use de::{
|
||||
Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor,
|
||||
};
|
||||
|
||||
/// An efficient way of discarding data from a deserializer.
|
||||
///
|
||||
@ -205,6 +207,13 @@ impl<'de> Visitor<'de> for IgnoredAny {
|
||||
let _ = bytes;
|
||||
Ok(IgnoredAny)
|
||||
}
|
||||
|
||||
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: EnumAccess<'de>,
|
||||
{
|
||||
data.variant::<IgnoredAny>()?.1.newtype_variant()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for IgnoredAny {
|
||||
|
@ -124,6 +124,19 @@ enum EnumOther {
|
||||
Other,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct IgnoredAny;
|
||||
|
||||
impl<'de> Deserialize<'de> for IgnoredAny {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
serde::de::IgnoredAny::deserialize(deserializer)?;
|
||||
Ok(IgnoredAny)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
macro_rules! declare_tests {
|
||||
@ -929,6 +942,21 @@ declare_tests! {
|
||||
Token::SeqEnd,
|
||||
],
|
||||
}
|
||||
test_ignored_any {
|
||||
IgnoredAny => &[
|
||||
Token::Str("s"),
|
||||
],
|
||||
IgnoredAny => &[
|
||||
Token::Seq { len: Some(1) },
|
||||
Token::Bool(true),
|
||||
Token::SeqEnd,
|
||||
],
|
||||
IgnoredAny => &[
|
||||
Token::Enum { name: "E" },
|
||||
Token::Str("Rust"),
|
||||
Token::Unit,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
declare_tests! {
|
||||
|
104
test_suite/tests/test_ignored_any.rs
Normal file
104
test_suite/tests/test_ignored_any.rs
Normal file
@ -0,0 +1,104 @@
|
||||
use serde::de::value::{Error, MapDeserializer, SeqDeserializer};
|
||||
use serde::de::{
|
||||
DeserializeSeed, EnumAccess, IgnoredAny, IntoDeserializer, VariantAccess, Visitor,
|
||||
};
|
||||
use serde::{forward_to_deserialize_any, Deserialize, Deserializer};
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
enum Target {
|
||||
Unit,
|
||||
Newtype(i32),
|
||||
Tuple(i32, i32),
|
||||
Struct { a: i32 },
|
||||
}
|
||||
|
||||
struct Enum(&'static str);
|
||||
|
||||
impl<'de> Deserializer<'de> for Enum {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_enum(self)
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
||||
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
||||
tuple_struct map struct enum identifier ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> EnumAccess<'de> for Enum {
|
||||
type Error = Error;
|
||||
type Variant = Self;
|
||||
|
||||
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
|
||||
where
|
||||
V: DeserializeSeed<'de>,
|
||||
{
|
||||
let v = seed.deserialize(self.0.into_deserializer())?;
|
||||
Ok((v, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> VariantAccess<'de> for Enum {
|
||||
type Error = Error;
|
||||
|
||||
fn unit_variant(self) -> Result<(), Self::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
seed.deserialize(10i32.into_deserializer())
|
||||
}
|
||||
|
||||
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let seq = SeqDeserializer::new(vec![1i32, 2].into_iter());
|
||||
visitor.visit_seq(seq)
|
||||
}
|
||||
|
||||
fn struct_variant<V>(
|
||||
self,
|
||||
_fields: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let map = MapDeserializer::new(vec![("a", 10i32)].into_iter());
|
||||
visitor.visit_map(map)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_enum() {
|
||||
// First just make sure the Deserializer impl works
|
||||
assert_eq!(Target::Unit, Target::deserialize(Enum("Unit")).unwrap());
|
||||
assert_eq!(
|
||||
Target::Newtype(10),
|
||||
Target::deserialize(Enum("Newtype")).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Target::Tuple(1, 2),
|
||||
Target::deserialize(Enum("Tuple")).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Target::Struct { a: 10 },
|
||||
Target::deserialize(Enum("Struct")).unwrap()
|
||||
);
|
||||
|
||||
// Now try IgnoredAny
|
||||
IgnoredAny::deserialize(Enum("Unit")).unwrap();
|
||||
IgnoredAny::deserialize(Enum("Newtype")).unwrap();
|
||||
IgnoredAny::deserialize(Enum("Tuple")).unwrap();
|
||||
IgnoredAny::deserialize(Enum("Struct")).unwrap();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user