Deserialize enum in Value

This commit is contained in:
Vincent Prouillet 2017-04-25 13:57:35 +09:00
parent 36f33ff3b3
commit c675b4f259
2 changed files with 89 additions and 2 deletions

View file

@ -209,7 +209,7 @@ impl<'de, 'b> de::Deserializer<'de> for &'b mut Deserializer<'de> {
if self.peek_char()? == '"' { if self.peek_char()? == '"' {
// Visit a unit variant. // Visit a unit variant.
match self.next()?.unwrap() { match self.next()?.unwrap() {
Token::String { ref val, ..} => { Token::String { ref val, .. } => {
visitor.visit_enum(val.clone().into_deserializer()) visitor.visit_enum(val.clone().into_deserializer())
}, },
_ => Err(Error::from_kind(ErrorKind::ExpectedString)) _ => Err(Error::from_kind(ErrorKind::ExpectedString))
@ -602,6 +602,7 @@ impl<'de> de::MapAccess<'de> for InlineTableDeserializer<'de> {
} }
} }
impl<'a> Deserializer<'a> { impl<'a> Deserializer<'a> {
/// Creates a new deserializer which will be deserializing the string /// Creates a new deserializer which will be deserializing the string
/// provided. /// provided.
@ -1229,6 +1230,7 @@ impl<'a> Header<'a> {
} }
} }
#[derive(Debug)]
enum Value<'a> { enum Value<'a> {
Integer(i64), Integer(i64),
Float(f64), Float(f64),

View file

@ -8,6 +8,7 @@ use std::vec;
use serde::ser; use serde::ser;
use serde::de; use serde::de;
use serde::de::IntoDeserializer;
pub use datetime::{Datetime, DatetimeParseError}; pub use datetime::{Datetime, DatetimeParseError};
use datetime::{DatetimeFromString, SERDE_STRUCT_FIELD_NAME}; use datetime::{DatetimeFromString, SERDE_STRUCT_FIELD_NAME};
@ -505,6 +506,31 @@ impl<'de> de::Deserializer<'de> for Value {
} }
} }
#[inline]
fn deserialize_enum<V>(
self,
_name: &str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, ::de::Error>
where
V: de::Visitor<'de>,
{
let (variant, value) = match self {
Value::String(variant) => (variant, None),
_ => {
return Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"string only"),);
}
};
visitor.visit_enum(
EnumDeserializer {
variant: variant,
value: value,
},
)
}
// `None` is interpreted as a missing field so be sure to implement `Some` // `None` is interpreted as a missing field so be sure to implement `Some`
// as a present field. // as a present field.
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, ::de::Error> fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, ::de::Error>
@ -516,9 +542,68 @@ impl<'de> de::Deserializer<'de> for Value {
forward_to_deserialize_any! { forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
bytes byte_buf map unit_struct tuple_struct struct bytes byte_buf map unit_struct tuple_struct struct
tuple ignored_any enum newtype_struct identifier tuple ignored_any newtype_struct identifier
} }
} }
struct EnumDeserializer {
variant: String,
value: Option<Value>,
}
impl<'de> de::EnumAccess<'de> for EnumDeserializer {
type Error = ::de::Error;
type Variant = VariantDeserializer;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Self::Error>
where
V: de::DeserializeSeed<'de>,
{
let variant = self.variant.into_deserializer();
let visitor = VariantDeserializer { value: self.value };
seed.deserialize(variant).map(|v| (v, visitor))
}
}
struct VariantDeserializer {
value: Option<Value>,
}
impl<'de> de::VariantAccess<'de> for VariantDeserializer {
type Error = ::de::Error;
fn unit_variant(self) -> Result<(), Self::Error> {
match self.value {
Some(value) => de::Deserialize::deserialize(value),
None => Ok(()),
}
}
fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant"))
}
fn tuple_variant<V>(self, _len: usize, _: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"))
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
_: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"))
}
}
struct SeqDeserializer { struct SeqDeserializer {
iter: vec::IntoIter<Value>, iter: vec::IntoIter<Value>,