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