mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 20:41:02 +00:00
Introduce a forward_deserializer macro.
It helps to create deserializers that can stop time: save the value and then use visitor to get it later!
This commit is contained in:
+109
-82
@@ -30,8 +30,8 @@ use ser;
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// For structs that contain a PhantomData. We do not want the trait
|
/// For structs that contain a PhantomData. We do not want the trait
|
||||||
// bound `E: Clone` inferred by derive(Clone).
|
/// bound `E: Clone` inferred by derive(Clone).
|
||||||
macro_rules! impl_copy_clone {
|
macro_rules! impl_copy_clone {
|
||||||
($ty:ident $(<$lifetime:tt>)*) => {
|
($ty:ident $(<$lifetime:tt>)*) => {
|
||||||
impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {}
|
impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {}
|
||||||
@@ -44,6 +44,100 @@ macro_rules! impl_copy_clone {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a deserializer any method of which forwards to the specified visitor method
|
||||||
|
macro_rules! forward_deserializer {
|
||||||
|
// Non-borrowed references
|
||||||
|
(
|
||||||
|
$(#[$doc:meta])*
|
||||||
|
// Actually, * in lifetime should be ?, but that syntax is not supported
|
||||||
|
// on old Rust versions (<= 1.28) or in 2015 edition
|
||||||
|
ref $deserializer:ident $(<$lifetime:tt>)* ($ty:ty) => $visit:ident
|
||||||
|
) => {
|
||||||
|
$(#[$doc])*
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct $deserializer<$($lifetime,)* E> {
|
||||||
|
value: $ty,
|
||||||
|
marker: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$($lifetime,)* E> $deserializer<$($lifetime,)* E> {
|
||||||
|
/// Create a new deserializer from the given value.
|
||||||
|
pub fn new(value: $ty) -> Self {
|
||||||
|
$deserializer {
|
||||||
|
value: value,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_copy_clone!($deserializer $(<$lifetime>)*);
|
||||||
|
|
||||||
|
impl<'de, $($lifetime,)* E> de::Deserializer<'de> for $deserializer<$($lifetime,)* E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: de::Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.$visit(self.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Borrowed references
|
||||||
|
(
|
||||||
|
$(#[$doc:meta])*
|
||||||
|
borrowed $deserializer:ident($ty:ty) => $visit:ident
|
||||||
|
) => {
|
||||||
|
$(#[$doc])*
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct $deserializer<'de, E> {
|
||||||
|
value: $ty,
|
||||||
|
marker: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, E> $deserializer<'de, E> {
|
||||||
|
/// Create a new borrowed deserializer from the given value.
|
||||||
|
pub fn new(value: $ty) -> Self {
|
||||||
|
$deserializer {
|
||||||
|
value: value,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_copy_clone!($deserializer<'de>);
|
||||||
|
|
||||||
|
impl<'de, E> de::Deserializer<'de> for $deserializer<'de, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: de::Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.$visit(self.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// A minimal representation of all possible errors that can occur using the
|
/// A minimal representation of all possible errors that can occur using the
|
||||||
@@ -665,86 +759,19 @@ where
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// A deserializer holding a `&[u8]`.
|
forward_deserializer!(
|
||||||
#[derive(Debug)]
|
/// A deserializer holding a `&[u8]`. Always call [`Visitor::visit_bytes`]
|
||||||
pub struct BytesDeserializer<'a, E> {
|
///
|
||||||
value: &'a [u8],
|
/// [`Visitor::visit_bytes`]: ../struct.Visitor.html#method.visit_bytes
|
||||||
marker: PhantomData<E>,
|
ref BytesDeserializer<'a>(&'a [u8]) => visit_bytes
|
||||||
}
|
);
|
||||||
|
forward_deserializer!(
|
||||||
impl_copy_clone!(BytesDeserializer<'de>);
|
/// A deserializer holding a `&[u8]` with a lifetime tied to another
|
||||||
|
/// deserializer. Always call [`Visitor::visit_borrowed_bytes`]
|
||||||
impl<'a, E> BytesDeserializer<'a, E> {
|
///
|
||||||
/// Create a new deserializer from the given slice.
|
/// [`Visitor::visit_borrowed_bytes`]: ../struct.Visitor.html#method.visit_borrowed_bytes
|
||||||
pub fn new(value: &'a [u8]) -> Self {
|
borrowed BorrowedBytesDeserializer(&'de [u8]) => visit_borrowed_bytes
|
||||||
BytesDeserializer {
|
);
|
||||||
value: value,
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, 'a, E> de::Deserializer<'de> for BytesDeserializer<'a, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where
|
|
||||||
V: de::Visitor<'de>,
|
|
||||||
{
|
|
||||||
visitor.visit_bytes(self.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/// A deserializer holding a `&[u8]` with a lifetime tied to another
|
|
||||||
/// deserializer.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct BorrowedBytesDeserializer<'de, E> {
|
|
||||||
value: &'de [u8],
|
|
||||||
marker: PhantomData<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_copy_clone!(BorrowedBytesDeserializer<'de>);
|
|
||||||
|
|
||||||
impl<'de, E> BorrowedBytesDeserializer<'de, E> {
|
|
||||||
/// Create a new borrowed deserializer from the given byte slice.
|
|
||||||
pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> {
|
|
||||||
BorrowedBytesDeserializer {
|
|
||||||
value: value,
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, E> de::Deserializer<'de> for BorrowedBytesDeserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where
|
|
||||||
V: de::Visitor<'de>,
|
|
||||||
{
|
|
||||||
visitor.visit_borrowed_bytes(self.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user