diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs new file mode 100644 index 00000000..d51f7386 --- /dev/null +++ b/serde/src/de/ignored_any.rs @@ -0,0 +1,104 @@ +use core::fmt; + +use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; + +/// A target for deserializers that want to ignore data. Implements Deserialize +/// and silently eats data given to it. +pub struct IgnoredAny; + +impl<'de> Deserialize<'de> for IgnoredAny { + #[inline] + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> + { + struct IgnoredAnyVisitor; + + impl<'de> Visitor<'de> for IgnoredAnyVisitor { + type Value = IgnoredAny; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("anything at all") + } + + #[inline] + fn visit_bool(self, _: bool) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_i64(self, _: i64) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_u64(self, _: u64) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_f64(self, _: f64) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_str(self, _: &str) -> Result + where E: Error + { + Ok(IgnoredAny) + } + + #[inline] + fn visit_none(self) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_some(self, _: D) -> Result + where D: Deserializer<'de> + { + Ok(IgnoredAny) + } + + #[inline] + fn visit_newtype_struct(self, _: D) -> Result + where D: Deserializer<'de> + { + Ok(IgnoredAny) + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_seq(self, mut visitor: V) -> Result + where V: SeqVisitor<'de> + { + while let Some(_) = try!(visitor.visit::()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_map(self, mut visitor: V) -> Result + where V: MapVisitor<'de> + { + while let Some((_, _)) = try!(visitor.visit::()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_bytes(self, _: &[u8]) -> Result + where E: Error + { + Ok(IgnoredAny) + } + } + + deserializer.deserialize_ignored_any(IgnoredAnyVisitor) + } +} diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 1aa91db5..d30392f6 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1,5 +1,3 @@ -//! This module contains `Deserialize` and `Visitor` implementations. - #[cfg(feature = "std")] use std::borrow::Cow; #[cfg(all(feature = "collections", not(feature = "std")))] @@ -65,8 +63,7 @@ use bytes::ByteBuf; /////////////////////////////////////////////////////////////////////////////// -/// A visitor that produces a `()`. -pub struct UnitVisitor; +struct UnitVisitor; impl<'de> Visitor<'de> for UnitVisitor { type Value = (); @@ -92,8 +89,7 @@ impl<'de> Deserialize<'de> for () { /////////////////////////////////////////////////////////////////////////////// -/// A visitor that produces a `bool`. -pub struct BoolVisitor; +struct BoolVisitor; impl<'de> Visitor<'de> for BoolVisitor { type Value = bool; @@ -408,8 +404,7 @@ impl<'de, T> Deserialize<'de> for Option /////////////////////////////////////////////////////////////////////////////// -/// A visitor that produces a `PhantomData`. -pub struct PhantomDataVisitor { +struct PhantomDataVisitor { marker: PhantomData, } @@ -448,14 +443,12 @@ macro_rules! seq_impl { $with_capacity:expr, $insert:expr ) => { - /// A visitor that produces a sequence. - pub struct $visitor_ty { + struct $visitor_ty { marker: PhantomData<$ty>, } impl $visitor_ty { - /// Construct a new sequence visitor. - pub fn new() -> Self { + fn new() -> Self { $visitor_ty { marker: PhantomData, } @@ -561,7 +554,7 @@ struct ArrayVisitor { } impl ArrayVisitor { - pub fn new() -> Self { + fn new() -> Self { ArrayVisitor { marker: PhantomData } } } @@ -673,14 +666,12 @@ array_impls! { macro_rules! tuple_impls { ($($len:expr => $visitor:ident => ($($n:tt $name:ident)+))+) => { $( - /// Construct a tuple visitor. - pub struct $visitor<$($name,)+> { + struct $visitor<$($name,)+> { marker: PhantomData<($($name,)+)>, } impl<$($name,)+> $visitor<$($name,)+> { - /// Construct a `TupleVisitor*`. - pub fn new() -> Self { + fn new() -> Self { $visitor { marker: PhantomData } } } @@ -749,14 +740,12 @@ macro_rules! map_impl { $ctor:expr, $with_capacity:expr ) => { - /// A visitor that produces a map. - pub struct $visitor_ty { + struct $visitor_ty { marker: PhantomData<$ty>, } impl $visitor_ty { - /// Construct a `MapVisitor*`. - pub fn new() -> Self { + fn new() -> Self { $visitor_ty { marker: PhantomData, } @@ -1498,107 +1487,3 @@ impl<'de, T, E> Deserialize<'de> for Result deserializer.deserialize_enum("Result", VARIANTS, ResultVisitor(PhantomData)) } } - -/////////////////////////////////////////////////////////////////////////////// - -/// A target for deserializers that want to ignore data. Implements -/// Deserialize and silently eats data given to it. -pub struct IgnoredAny; - -impl<'de> Deserialize<'de> for IgnoredAny { - #[inline] - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> - { - struct IgnoredAnyVisitor; - - impl<'de> Visitor<'de> for IgnoredAnyVisitor { - type Value = IgnoredAny; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("anything at all") - } - - #[inline] - fn visit_bool(self, _: bool) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_i64(self, _: i64) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_u64(self, _: u64) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_f64(self, _: f64) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_str(self, _: &str) -> Result - where E: Error - { - Ok(IgnoredAny) - } - - #[inline] - fn visit_none(self) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_some(self, _: D) -> Result - where D: Deserializer<'de> - { - Ok(IgnoredAny) - } - - #[inline] - fn visit_newtype_struct(self, _: D) -> Result - where D: Deserializer<'de> - { - Ok(IgnoredAny) - } - - #[inline] - fn visit_unit(self) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor<'de> - { - while let Some(_) = try!(visitor.visit::()) { - // Gobble - } - Ok(IgnoredAny) - } - - #[inline] - fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor<'de> - { - while let Some((_, _)) = try!(visitor.visit::()) { - // Gobble - } - Ok(IgnoredAny) - } - - #[inline] - fn visit_bytes(self, _: &[u8]) -> Result - where E: Error - { - Ok(IgnoredAny) - } - } - - // TODO maybe not necessary with impl specialization - deserializer.deserialize_ignored_any(IgnoredAnyVisitor) - } -} diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index ad6944ba..c9b427f2 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -107,10 +107,11 @@ use core::marker::PhantomData; /////////////////////////////////////////////////////////////////////////////// -#[doc(hidden)] -pub mod impls; pub mod value; + mod from_primitive; +mod ignored_any; +mod impls; // Helpers used by generated code. Not public API. #[doc(hidden)] @@ -118,6 +119,8 @@ pub mod private; #[cfg(any(feature = "std", feature = "collections"))] mod content; +pub use self::ignored_any::IgnoredAny; + /////////////////////////////////////////////////////////////////////////////// /// The `Error` trait allows `Deserialize` implementations to create descriptive diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index b67ad285..84be769b 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1288,7 +1288,7 @@ fn deserialize_map(ident: &syn::Ident, None } else { Some(quote! { - _ => { let _ = try!(_serde::de::MapVisitor::visit_value::<_serde::de::impls::IgnoredAny>(&mut __visitor)); } + _ => { let _ = try!(_serde::de::MapVisitor::visit_value::<_serde::de::IgnoredAny>(&mut __visitor)); } }) };