Auto merge of #525 - serde-rs:forward, r=oli-obk

Expose forward_to_deserialize macro

Fixes #522.

```rust
impl Deserializer for MyDeserializer {
    fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
        where V: Visitor
    {
        /* ... */
    }

    forward_to_deserialize! {
        bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
        unit option seq seq_fixed_size bytes map unit_struct newtype_struct
        tuple_struct struct struct_field tuple enum ignored_any
    }
}
```

cc @nox
This commit is contained in:
Homu
2016-09-06 00:37:18 +09:00
4 changed files with 231 additions and 239 deletions
-65
View File
@@ -11,71 +11,6 @@ use collections::{String, Vec};
use core::fmt; use core::fmt;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Macro helper to not have to re-implement all the defaulted methods.
/// Every given method ignores all arguments and forwards to `deserialize`.
/// Note that `deserialize_enum` simply returns an `Error::invalid_type`.
macro_rules! de_forward_to_deserialize {
($($func:ident),*) => {
$(de_forward_to_deserialize!{func: $func})*
};
(func: deserialize_unit_struct) => {
de_forward_to_deserialize!{named: deserialize_unit_struct}
};
(func: deserialize_newtype_struct) => {
de_forward_to_deserialize!{named: deserialize_newtype_struct}
};
(func: deserialize_tuple) => {
de_forward_to_deserialize!{tup_fn: deserialize_tuple}
};
(func: deserialize_seq_fixed_size) => {
de_forward_to_deserialize!{tup_fn: deserialize_seq_fixed_size}
};
(func: deserialize_tuple_struct) => {
#[inline]
fn deserialize_tuple_struct<__V>(&mut self, _: &str, _: usize, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
(func: deserialize_struct) => {
#[inline]
fn deserialize_struct<__V>(&mut self, _: &str, _: &[&str], visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
(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))
}
};
(named: $func:ident) => {
#[inline]
fn $func<__V>(&mut self, _: &str, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
(tup_fn: $func: ident) => {
#[inline]
fn $func<__V>(&mut self, _: usize, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
(func: $func:ident) => {
#[inline]
fn $func<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
}
///////////////////////////////////////////////////////////////////////////////
// modules come after macros
pub mod impls; pub mod impls;
pub mod value; pub mod value;
+49 -174
View File
@@ -178,20 +178,10 @@ impl<E> de::Deserializer for UnitDeserializer<E>
{ {
type Error = E; type Error = E;
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit seq seq_fixed_size bytes map unit_struct newtype_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, tuple_struct struct struct_field tuple enum ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct
} }
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error>
@@ -229,21 +219,11 @@ macro_rules! primitive_deserializer {
{ {
type Error = E; type Error = E;
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
deserialize_f64, deserialize_f32, string unit option seq seq_fixed_size bytes map unit_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, newtype_struct tuple_struct struct struct_field tuple enum
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize, ignored_any
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error>
@@ -311,20 +291,10 @@ impl<'a, E> de::Deserializer for StrDeserializer<'a, E>
visitor.visit(self) visitor.visit(self)
} }
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option seq seq_fixed_size bytes map unit_struct newtype_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, tuple_struct struct struct_field tuple ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
} }
@@ -408,20 +378,10 @@ impl<E> de::Deserializer for StringDeserializer<E>
visitor.visit(self) visitor.visit(self)
} }
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option seq seq_fixed_size bytes map unit_struct newtype_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, tuple_struct struct struct_field tuple ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
} }
@@ -507,20 +467,10 @@ impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E>
visitor.visit(self) visitor.visit(self)
} }
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option seq seq_fixed_size bytes map unit_struct newtype_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, tuple_struct struct struct_field tuple ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
} }
@@ -599,21 +549,10 @@ impl<I, T, E> de::Deserializer for SeqDeserializer<I, E>
visitor.visit_seq(self) visitor.visit_seq(self)
} }
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option seq seq_fixed_size bytes map unit_struct newtype_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, tuple_struct struct struct_field tuple enum ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
} }
@@ -722,21 +661,10 @@ impl<V_, E> de::Deserializer for SeqVisitorDeserializer<V_, E>
visitor.visit_seq(&mut self.visitor) visitor.visit_seq(&mut self.visitor)
} }
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option seq seq_fixed_size bytes map unit_struct newtype_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, tuple_struct struct struct_field tuple enum ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
} }
@@ -822,20 +750,10 @@ impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
} }
} }
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option bytes map unit_struct newtype_struct tuple_struct struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, struct_field tuple enum ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
} }
@@ -928,19 +846,10 @@ impl<A, B, E> de::Deserializer for PairDeserializer<A, B, E>
{ {
type Error = E; type Error = E;
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option bytes map unit_struct newtype_struct tuple_struct struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, struct_field tuple enum ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit, deserialize_option,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct
} }
fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
@@ -1075,21 +984,10 @@ impl<V_, E> de::Deserializer for MapVisitorDeserializer<V_, E>
visitor.visit_map(&mut self.visitor) visitor.visit_map(&mut self.visitor)
} }
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option seq seq_fixed_size bytes map unit_struct newtype_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, tuple_struct struct struct_field tuple enum ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
} }
@@ -1122,25 +1020,13 @@ impl<'a, E> de::Deserializer for BytesDeserializer<'a, E>
} }
} }
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option seq seq_fixed_size bytes map unit_struct newtype_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, tuple_struct struct struct_field tuple enum ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
@@ -1173,20 +1059,9 @@ impl<E> de::Deserializer for ByteBufDeserializer<E>
} }
} }
de_forward_to_deserialize!{ forward_to_deserialize! {
deserialize_bool, bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
deserialize_f64, deserialize_f32, unit option seq seq_fixed_size bytes map unit_struct newtype_struct
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize, tuple_struct struct struct_field tuple enum ignored_any
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
} }
} }
+3
View File
@@ -45,6 +45,9 @@ macro_rules! format {
($s:expr, $($rest:tt)*) => ($s) ($s:expr, $($rest:tt)*) => ($s)
} }
#[macro_use]
mod macros;
pub mod bytes; pub mod bytes;
pub mod de; pub mod de;
#[cfg(feature = "std")] #[cfg(feature = "std")]
+179
View File
@@ -0,0 +1,179 @@
#[cfg(feature = "std")]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => {
#[inline]
fn $func<__V>(&mut self, $(_: $arg,)* visitor: __V) -> ::std::result::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor
{
self.deserialize(visitor)
}
};
}
#[cfg(not(feature = "std"))]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => {
#[inline]
fn $func<__V>(&mut self, $(_: $arg,)* visitor: __V) -> ::core::result::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor
{
self.deserialize(visitor)
}
};
}
#[cfg(feature = "std")]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_enum {
() => {
#[inline]
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _: __V) -> ::std::result::Result<__V::Value, Self::Error>
where __V: $crate::de::EnumVisitor
{
Err($crate::de::Error::invalid_type($crate::de::Type::Enum))
}
};
}
#[cfg(not(feature = "std"))]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_enum {
() => {
#[inline]
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _: __V) -> ::core::result::Result<__V::Value, Self::Error>
where __V: $crate::de::EnumVisitor
{
Err($crate::de::Error::invalid_type($crate::de::Type::Enum))
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_helper {
(bool) => {
forward_to_deserialize_method!{deserialize_bool()}
};
(usize) => {
forward_to_deserialize_method!{deserialize_usize()}
};
(u8) => {
forward_to_deserialize_method!{deserialize_u8()}
};
(u16) => {
forward_to_deserialize_method!{deserialize_u16()}
};
(u32) => {
forward_to_deserialize_method!{deserialize_u32()}
};
(u64) => {
forward_to_deserialize_method!{deserialize_u64()}
};
(isize) => {
forward_to_deserialize_method!{deserialize_isize()}
};
(i8) => {
forward_to_deserialize_method!{deserialize_i8()}
};
(i16) => {
forward_to_deserialize_method!{deserialize_i16()}
};
(i32) => {
forward_to_deserialize_method!{deserialize_i32()}
};
(i64) => {
forward_to_deserialize_method!{deserialize_i64()}
};
(f32) => {
forward_to_deserialize_method!{deserialize_f32()}
};
(f64) => {
forward_to_deserialize_method!{deserialize_f64()}
};
(char) => {
forward_to_deserialize_method!{deserialize_char()}
};
(str) => {
forward_to_deserialize_method!{deserialize_str()}
};
(string) => {
forward_to_deserialize_method!{deserialize_string()}
};
(unit) => {
forward_to_deserialize_method!{deserialize_unit()}
};
(option) => {
forward_to_deserialize_method!{deserialize_option()}
};
(seq) => {
forward_to_deserialize_method!{deserialize_seq()}
};
(seq_fixed_size) => {
forward_to_deserialize_method!{deserialize_seq_fixed_size(usize)}
};
(bytes) => {
forward_to_deserialize_method!{deserialize_bytes()}
};
(map) => {
forward_to_deserialize_method!{deserialize_map()}
};
(unit_struct) => {
forward_to_deserialize_method!{deserialize_unit_struct(&'static str)}
};
(newtype_struct) => {
forward_to_deserialize_method!{deserialize_newtype_struct(&'static str)}
};
(tuple_struct) => {
forward_to_deserialize_method!{deserialize_tuple_struct(&'static str, usize)}
};
(struct) => {
forward_to_deserialize_method!{deserialize_struct(&'static str, &'static [&'static str])}
};
(struct_field) => {
forward_to_deserialize_method!{deserialize_struct_field()}
};
(tuple) => {
forward_to_deserialize_method!{deserialize_tuple(usize)}
};
(ignored_any) => {
forward_to_deserialize_method!{deserialize_ignored_any()}
};
(enum) => {
forward_to_deserialize_enum!();
};
}
/// Helper to forward `Deserializer` methods to `Deserializer::deserialize`.
/// Every given method ignores all arguments and forwards to `deserialize`.
/// Note that `deserialize_enum` simply returns an `Error::invalid_type`; a
/// better approach is tracked in [serde-rs/serde#521][1].
///
/// ```rust,ignore
/// impl Deserializer for MyDeserializer {
/// fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor
/// {
/// /* ... */
/// }
///
/// forward_to_deserialize! {
/// bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
/// unit option seq seq_fixed_size bytes map unit_struct newtype_struct
/// tuple_struct struct struct_field tuple enum ignored_any
/// }
/// }
/// ```
///
/// [1]: https://github.com/serde-rs/serde/issues/521
#[macro_export]
macro_rules! forward_to_deserialize {
($($func:ident)*) => {
$(forward_to_deserialize_helper!{$func})*
};
}