Generate deserialize impls for identifiers

This commit is contained in:
David Tolnay
2017-04-14 16:09:00 -07:00
parent 30e8c84d01
commit cdfd445528
17 changed files with 745 additions and 103 deletions
+108 -1
View File
@@ -8,7 +8,7 @@
use lib::*;
use de::{Deserialize, Deserializer, Error, Visitor};
use de::{Deserialize, Deserializer, IntoDeserializer, Error, Visitor};
#[cfg(any(feature = "std", feature = "collections"))]
use de::Unexpected;
@@ -1740,3 +1740,110 @@ mod content {
}
}
}
////////////////////////////////////////////////////////////////////////////////
// Like `IntoDeserializer` but also implemented for `&[u8]`. This is used for
// the newtype fallthrough case of `field_identifier`.
//
// #[derive(Deserialize)]
// #[serde(field_identifier)]
// enum F {
// A,
// B,
// Other(String), // deserialized using IdentifierDeserializer
// }
pub trait IdentifierDeserializer<'de, E: Error> {
type Deserializer: Deserializer<'de, Error = E>;
fn from(self) -> Self::Deserializer;
}
impl<'de, E> IdentifierDeserializer<'de, E> for u32
where
E: Error,
{
type Deserializer = <u32 as IntoDeserializer<'de, E>>::Deserializer;
fn from(self) -> Self::Deserializer {
self.into_deserializer()
}
}
pub struct StrDeserializer<'a, E> {
value: &'a str,
marker: PhantomData<E>,
}
impl<'a, E> IdentifierDeserializer<'a, E> for &'a str
where
E: Error,
{
type Deserializer = StrDeserializer<'a, E>;
fn from(self) -> Self::Deserializer {
StrDeserializer {
value: self,
marker: PhantomData,
}
}
}
impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E>
where
E: Error,
{
type Error = E;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_str(self.value)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq seq_fixed_size
tuple tuple_struct map struct identifier enum ignored_any
}
}
pub struct BytesDeserializer<'a, E> {
value: &'a [u8],
marker: PhantomData<E>,
}
impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8]
where
E: Error,
{
type Deserializer = BytesDeserializer<'a, E>;
fn from(self) -> Self::Deserializer {
BytesDeserializer {
value: self,
marker: PhantomData,
}
}
}
impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
where
E: Error,
{
type Error = E;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_bytes(self.value)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq seq_fixed_size
tuple tuple_struct map struct identifier enum ignored_any
}
}