Enum deserialization API
This commit is contained in:
parent
123e040189
commit
85f1bf0259
@ -65,7 +65,6 @@ use core::num::Zero;
|
||||
use de::{
|
||||
Deserialize,
|
||||
Deserializer,
|
||||
EnumVisitor,
|
||||
Error,
|
||||
MapVisitor,
|
||||
SeqVisitor,
|
||||
@ -1145,7 +1144,7 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
|
||||
{
|
||||
struct FieldVisitor;
|
||||
|
||||
impl ::de::Visitor for FieldVisitor {
|
||||
impl Visitor for FieldVisitor {
|
||||
type Value = Field;
|
||||
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
@ -1194,15 +1193,15 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
|
||||
}
|
||||
}
|
||||
|
||||
struct Visitor<T, E>(PhantomData<Result<T, E>>);
|
||||
struct ResultVisitor<T, E>(PhantomData<Result<T, E>>);
|
||||
|
||||
impl<T, E> EnumVisitor for Visitor<T, E>
|
||||
impl<T, E> Visitor for ResultVisitor<T, E>
|
||||
where T: Deserialize,
|
||||
E: Deserialize
|
||||
{
|
||||
type Value = Result<T, E>;
|
||||
|
||||
fn visit<V>(&mut self, mut visitor: V) -> Result<Result<T, E>, V::Error>
|
||||
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<Result<T, E>, V::Error>
|
||||
where V: VariantVisitor
|
||||
{
|
||||
match try!(visitor.visit_variant()) {
|
||||
@ -1220,7 +1219,7 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
|
||||
|
||||
const VARIANTS: &'static [&'static str] = &["Ok", "Err"];
|
||||
|
||||
deserializer.deserialize_enum("Result", VARIANTS, Visitor(PhantomData))
|
||||
deserializer.deserialize_enum("Result", VARIANTS, ResultVisitor(PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,9 @@ macro_rules! de_forward_to_deserialize {
|
||||
};
|
||||
(func: deserialize_enum) => {
|
||||
#[inline]
|
||||
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _: __V) -> Result<__V::Value, Self::Error>
|
||||
where __V: $crate::de::EnumVisitor {
|
||||
Err($crate::de::Error::invalid_type($crate::de::Type::Enum))
|
||||
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], visitor: __V) -> Result<__V::Value, Self::Error>
|
||||
where __V: $crate::de::Visitor {
|
||||
self.deserialize(visitor)
|
||||
}
|
||||
};
|
||||
(named: $func:ident) => {
|
||||
@ -234,6 +234,9 @@ pub enum Type {
|
||||
/// Represents a unit variant.
|
||||
UnitVariant,
|
||||
|
||||
/// Represents a newtype variant.
|
||||
NewtypeVariant,
|
||||
|
||||
/// Represents a `&[u8]` type.
|
||||
Bytes,
|
||||
}
|
||||
@ -241,38 +244,39 @@ pub enum Type {
|
||||
impl fmt::Display for Type {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
let display = match *self {
|
||||
Type::Bool => "bool",
|
||||
Type::Usize => "usize",
|
||||
Type::U8 => "u8",
|
||||
Type::U16 => "u16",
|
||||
Type::U32 => "u32",
|
||||
Type::U64 => "u64",
|
||||
Type::Isize => "isize",
|
||||
Type::I8 => "i8",
|
||||
Type::I16 => "i16",
|
||||
Type::I32 => "i32",
|
||||
Type::I64 => "i64",
|
||||
Type::F32 => "f32",
|
||||
Type::F64 => "f64",
|
||||
Type::Char => "char",
|
||||
Type::Str => "str",
|
||||
Type::String => "string",
|
||||
Type::Unit => "unit",
|
||||
Type::Option => "option",
|
||||
Type::Seq => "seq",
|
||||
Type::Map => "map",
|
||||
Type::UnitStruct => "unit struct",
|
||||
Type::NewtypeStruct => "newtype struct",
|
||||
Type::TupleStruct => "tuple struct",
|
||||
Type::Struct => "struct",
|
||||
Type::FieldName => "field name",
|
||||
Type::Tuple => "tuple",
|
||||
Type::Enum => "enum",
|
||||
Type::VariantName => "variant name",
|
||||
Type::StructVariant => "struct variant",
|
||||
Type::TupleVariant => "tuple variant",
|
||||
Type::UnitVariant => "unit variant",
|
||||
Type::Bytes => "bytes",
|
||||
Type::Bool => "bool",
|
||||
Type::Usize => "usize",
|
||||
Type::U8 => "u8",
|
||||
Type::U16 => "u16",
|
||||
Type::U32 => "u32",
|
||||
Type::U64 => "u64",
|
||||
Type::Isize => "isize",
|
||||
Type::I8 => "i8",
|
||||
Type::I16 => "i16",
|
||||
Type::I32 => "i32",
|
||||
Type::I64 => "i64",
|
||||
Type::F32 => "f32",
|
||||
Type::F64 => "f64",
|
||||
Type::Char => "char",
|
||||
Type::Str => "str",
|
||||
Type::String => "string",
|
||||
Type::Unit => "unit",
|
||||
Type::Option => "option",
|
||||
Type::Seq => "seq",
|
||||
Type::Map => "map",
|
||||
Type::UnitStruct => "unit struct",
|
||||
Type::NewtypeStruct => "newtype struct",
|
||||
Type::TupleStruct => "tuple struct",
|
||||
Type::Struct => "struct",
|
||||
Type::FieldName => "field name",
|
||||
Type::Tuple => "tuple",
|
||||
Type::Enum => "enum",
|
||||
Type::VariantName => "variant name",
|
||||
Type::StructVariant => "struct variant",
|
||||
Type::TupleVariant => "tuple variant",
|
||||
Type::UnitVariant => "unit variant",
|
||||
Type::NewtypeVariant => "newtype variant",
|
||||
Type::Bytes => "bytes",
|
||||
};
|
||||
display.fmt(formatter)
|
||||
}
|
||||
@ -464,7 +468,7 @@ pub trait Deserializer {
|
||||
name: &'static str,
|
||||
variants: &'static [&'static str],
|
||||
visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: EnumVisitor;
|
||||
where V: Visitor;
|
||||
|
||||
/// This method hints that the `Deserialize` type needs to deserialize a value whose type
|
||||
/// doesn't matter because it is ignored.
|
||||
@ -656,6 +660,14 @@ pub trait Visitor {
|
||||
Err(Error::invalid_type(Type::Map))
|
||||
}
|
||||
|
||||
/// `visit_enum` deserializes a `VariantVisitor` into a `Value`.
|
||||
fn visit_enum<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
|
||||
where V: VariantVisitor,
|
||||
{
|
||||
let _ = visitor;
|
||||
Err(Error::invalid_type(Type::Enum))
|
||||
}
|
||||
|
||||
/// `visit_bytes` deserializes a `&[u8]` into a `Value`.
|
||||
fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
@ -808,19 +820,6 @@ impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// `EnumVisitor` is a visitor that is created by the `Deserialize` and passed to the
|
||||
/// `Deserializer` in order to deserialize enums.
|
||||
pub trait EnumVisitor {
|
||||
/// The value produced by this visitor.
|
||||
type Value;
|
||||
|
||||
/// Visit the specific variant with the `VariantVisitor`.
|
||||
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
|
||||
where V: VariantVisitor;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// `VariantVisitor` is a visitor that is created by the `Deserializer` and passed to the
|
||||
/// `Deserialize` in order to deserialize a specific enum variant.
|
||||
pub trait VariantVisitor {
|
||||
@ -832,9 +831,7 @@ pub trait VariantVisitor {
|
||||
where V: Deserialize;
|
||||
|
||||
/// `visit_unit` is called when deserializing a variant with no values.
|
||||
fn visit_unit(&mut self) -> Result<(), Self::Error> {
|
||||
Err(Error::invalid_type(Type::UnitVariant))
|
||||
}
|
||||
fn visit_unit(&mut self) -> Result<(), Self::Error>;
|
||||
|
||||
/// `visit_newtype` is called when deserializing a variant with a single value.
|
||||
/// A good default is often to use the `visit_tuple` method to deserialize a `(value,)`.
|
||||
|
@ -306,9 +306,9 @@ impl<'a, E> de::Deserializer for StrDeserializer<'a, E>
|
||||
_name: &str,
|
||||
_variants: &'static [&'static str],
|
||||
mut visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::EnumVisitor,
|
||||
where V: de::Visitor,
|
||||
{
|
||||
visitor.visit(self)
|
||||
visitor.visit_enum(self)
|
||||
}
|
||||
|
||||
de_forward_to_deserialize!{
|
||||
@ -346,8 +346,7 @@ impl<'a, E> de::VariantVisitor for StrDeserializer<'a, E>
|
||||
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
|
||||
where T: super::Deserialize,
|
||||
{
|
||||
let (value,) = try!(self.visit_tuple(1, super::impls::TupleVisitor1::new()));
|
||||
Ok(value)
|
||||
Err(super::Error::invalid_type(super::Type::NewtypeVariant))
|
||||
}
|
||||
|
||||
fn visit_tuple<V>(&mut self,
|
||||
@ -403,9 +402,9 @@ impl<E> de::Deserializer for StringDeserializer<E>
|
||||
_name: &str,
|
||||
_variants: &'static [&'static str],
|
||||
mut visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::EnumVisitor,
|
||||
where V: de::Visitor,
|
||||
{
|
||||
visitor.visit(self)
|
||||
visitor.visit_enum(self)
|
||||
}
|
||||
|
||||
de_forward_to_deserialize!{
|
||||
@ -444,8 +443,7 @@ impl<'a, E> de::VariantVisitor for StringDeserializer<E>
|
||||
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
|
||||
where T: super::Deserialize,
|
||||
{
|
||||
let (value,) = try!(self.visit_tuple(1, super::impls::TupleVisitor1::new()));
|
||||
Ok(value)
|
||||
Err(super::Error::invalid_type(super::Type::NewtypeVariant))
|
||||
}
|
||||
|
||||
fn visit_tuple<V>(&mut self,
|
||||
@ -502,9 +500,9 @@ impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E>
|
||||
_name: &str,
|
||||
_variants: &'static [&'static str],
|
||||
mut visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::EnumVisitor,
|
||||
where V: de::Visitor,
|
||||
{
|
||||
visitor.visit(self)
|
||||
visitor.visit_enum(self)
|
||||
}
|
||||
|
||||
de_forward_to_deserialize!{
|
||||
@ -543,8 +541,7 @@ impl<'a, E> de::VariantVisitor for CowStrDeserializer<'a, E>
|
||||
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
|
||||
where T: super::Deserialize,
|
||||
{
|
||||
let (value,) = try!(self.visit_tuple(1, super::impls::TupleVisitor1::new()));
|
||||
Ok(value)
|
||||
Err(super::Error::invalid_type(super::Type::NewtypeVariant))
|
||||
}
|
||||
|
||||
fn visit_tuple<V>(&mut self,
|
||||
|
@ -622,10 +622,10 @@ fn deserialize_item_enum(
|
||||
|
||||
$visitor_item
|
||||
|
||||
impl $impl_generics _serde::de::EnumVisitor for $visitor_ty $where_clause {
|
||||
impl $impl_generics _serde::de::Visitor for $visitor_ty $where_clause {
|
||||
type Value = $ty;
|
||||
|
||||
fn visit<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
|
||||
fn visit_enum<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
|
||||
where __V: _serde::de::VariantVisitor,
|
||||
{
|
||||
match try!(visitor.visit_variant()) {
|
||||
|
@ -3,7 +3,6 @@ use std::iter;
|
||||
use serde::de::{
|
||||
self,
|
||||
Deserialize,
|
||||
EnumVisitor,
|
||||
MapVisitor,
|
||||
SeqVisitor,
|
||||
VariantVisitor,
|
||||
@ -268,13 +267,13 @@ impl<I> de::Deserializer for Deserializer<I>
|
||||
name: &str,
|
||||
_variants: &'static [&'static str],
|
||||
mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: EnumVisitor,
|
||||
where V: Visitor,
|
||||
{
|
||||
match self.tokens.peek() {
|
||||
Some(&Token::EnumStart(n)) if name == n => {
|
||||
self.tokens.next();
|
||||
|
||||
visitor.visit(DeserializerVariantVisitor {
|
||||
visitor.visit_enum(DeserializerVariantVisitor {
|
||||
de: self,
|
||||
})
|
||||
}
|
||||
@ -282,7 +281,7 @@ impl<I> de::Deserializer for Deserializer<I>
|
||||
| Some(&Token::EnumNewType(n, _))
|
||||
| Some(&Token::EnumSeqStart(n, _, _))
|
||||
| Some(&Token::EnumMapStart(n, _, _)) if name == n => {
|
||||
visitor.visit(DeserializerVariantVisitor {
|
||||
visitor.visit_enum(DeserializerVariantVisitor {
|
||||
de: self,
|
||||
})
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ impl Deserializer for BytesDeserializer {
|
||||
self.deserialize(visitor)
|
||||
}
|
||||
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _visitor: __V)
|
||||
-> Result<__V::Value, Self::Error> where __V: de::EnumVisitor {
|
||||
-> Result<__V::Value, Self::Error> where __V: de::Visitor {
|
||||
Err(Error)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user