//! This module contains `Deserialize` and `Visitor` implementations. #[cfg(feature = "std")] use std::borrow::Cow; #[cfg(all(feature = "nightly", feature = "collections", not(feature = "std")))] use collections::borrow::Cow; #[cfg(all(feature = "collections", not(feature = "std")))] use collections::{ BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque, Vec, String, }; #[cfg(feature = "std")] use std::collections::{ HashMap, HashSet, BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque, }; #[cfg(all(feature = "nightly", feature = "collections"))] use collections::enum_set::{CLike, EnumSet}; #[cfg(all(feature = "nightly", feature = "collections"))] use collections::borrow::ToOwned; use core::hash::Hash; use core::marker::PhantomData; #[cfg(feature = "std")] use std::net; #[cfg(feature = "std")] use std::path; use core::str; #[cfg(feature = "std")] use std::rc::Rc; #[cfg(all(feature = "nightly", feature = "alloc", not(feature = "std")))] use alloc::rc::Rc; #[cfg(feature = "std")] use std::sync::Arc; #[cfg(all(feature = "nightly", feature = "alloc", not(feature = "std")))] use alloc::arc::Arc; #[cfg(all(feature = "nightly", feature = "alloc", not(feature = "std")))] use alloc::boxed::Box; #[cfg(feature = "nightly")] use core::nonzero::{NonZero, Zeroable}; #[cfg(feature = "nightly")] use core::num::Zero; use de::{ Deserialize, Deserializer, EnumVisitor, Error, MapVisitor, SeqVisitor, Type, VariantVisitor, Visitor, }; use de::from_primitive::FromPrimitive; /////////////////////////////////////////////////////////////////////////////// /// A visitor that produces a `()`. pub struct UnitVisitor; impl Visitor for UnitVisitor { type Value = (); fn visit_unit(&mut self) -> Result<(), E> where E: Error, { Ok(()) } fn visit_seq(&mut self, mut visitor: V) -> Result<(), V::Error> where V: SeqVisitor, { visitor.end() } } impl Deserialize for () { fn deserialize(deserializer: &mut D) -> Result<(), D::Error> where D: Deserializer, { deserializer.deserialize_unit(UnitVisitor) } } /////////////////////////////////////////////////////////////////////////////// /// A visitor that produces a `bool`. pub struct BoolVisitor; impl Visitor for BoolVisitor { type Value = bool; fn visit_bool(&mut self, v: bool) -> Result where E: Error, { Ok(v) } fn visit_str(&mut self, s: &str) -> Result where E: Error, { match s.trim_matches(::utils::Pattern_White_Space) { "true" => Ok(true), "false" => Ok(false), _ => Err(Error::invalid_type(Type::Bool)), } } } impl Deserialize for bool { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { deserializer.deserialize_bool(BoolVisitor) } } /////////////////////////////////////////////////////////////////////////////// macro_rules! impl_deserialize_num_method { ($src_ty:ty, $method:ident, $from_method:ident, $ty:expr) => { #[inline] fn $method(&mut self, v: $src_ty) -> Result where E: Error, { match FromPrimitive::$from_method(v) { Some(v) => Ok(v), None => Err(Error::invalid_type($ty)), } } } } /// A visitor that produces a primitive type. struct PrimitiveVisitor { marker: PhantomData, } impl PrimitiveVisitor { /// Construct a new `PrimitiveVisitor`. #[inline] fn new() -> Self { PrimitiveVisitor { marker: PhantomData, } } } impl Visitor for PrimitiveVisitor where T: Deserialize + FromPrimitive + str::FromStr { type Value = T; impl_deserialize_num_method!(isize, visit_isize, from_isize, Type::Isize); impl_deserialize_num_method!(i8, visit_i8, from_i8, Type::I8); impl_deserialize_num_method!(i16, visit_i16, from_i16, Type::I16); impl_deserialize_num_method!(i32, visit_i32, from_i32, Type::I32); impl_deserialize_num_method!(i64, visit_i64, from_i64, Type::I64); impl_deserialize_num_method!(usize, visit_usize, from_usize, Type::Usize); impl_deserialize_num_method!(u8, visit_u8, from_u8, Type::U8); impl_deserialize_num_method!(u16, visit_u16, from_u16, Type::U16); impl_deserialize_num_method!(u32, visit_u32, from_u32, Type::U32); impl_deserialize_num_method!(u64, visit_u64, from_u64, Type::U64); impl_deserialize_num_method!(f32, visit_f32, from_f32, Type::F32); impl_deserialize_num_method!(f64, visit_f64, from_f64, Type::F64); #[inline] fn visit_str(&mut self, s: &str) -> Result where E: Error, { str::FromStr::from_str(s.trim_matches(::utils::Pattern_White_Space)).or_else(|_| { Err(Error::invalid_type(Type::Str)) }) } } macro_rules! impl_deserialize_num { ($ty:ty, $method:ident) => { impl Deserialize for $ty { #[inline] fn deserialize(deserializer: &mut D) -> Result<$ty, D::Error> where D: Deserializer, { deserializer.$method(PrimitiveVisitor::new()) } } } } impl_deserialize_num!(isize, deserialize_isize); impl_deserialize_num!(i8, deserialize_i8); impl_deserialize_num!(i16, deserialize_i16); impl_deserialize_num!(i32, deserialize_i32); impl_deserialize_num!(i64, deserialize_i64); impl_deserialize_num!(usize, deserialize_usize); impl_deserialize_num!(u8, deserialize_u8); impl_deserialize_num!(u16, deserialize_u16); impl_deserialize_num!(u32, deserialize_u32); impl_deserialize_num!(u64, deserialize_u64); impl_deserialize_num!(f32, deserialize_f32); impl_deserialize_num!(f64, deserialize_f64); /////////////////////////////////////////////////////////////////////////////// struct CharVisitor; impl Visitor for CharVisitor { type Value = char; #[inline] fn visit_char(&mut self, v: char) -> Result where E: Error, { Ok(v) } #[inline] fn visit_str(&mut self, v: &str) -> Result where E: Error, { let mut iter = v.chars(); if let Some(v) = iter.next() { if iter.next().is_some() { Err(Error::invalid_type(Type::Char)) } else { Ok(v) } } else { Err(Error::end_of_stream()) } } } impl Deserialize for char { #[inline] fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { deserializer.deserialize_char(CharVisitor) } } /////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "collections"))] struct StringVisitor; #[cfg(any(feature = "std", feature = "collections"))] impl Visitor for StringVisitor { type Value = String; fn visit_str(&mut self, v: &str) -> Result where E: Error, { Ok(v.to_owned()) } fn visit_string(&mut self, v: String) -> Result where E: Error, { Ok(v) } fn visit_bytes(&mut self, v: &[u8]) -> Result where E: Error, { match str::from_utf8(v) { Ok(s) => Ok(s.to_owned()), Err(_) => Err(Error::invalid_type(Type::String)), } } fn visit_byte_buf(&mut self, v: Vec) -> Result where E: Error, { match String::from_utf8(v) { Ok(s) => Ok(s), Err(_) => Err(Error::invalid_type(Type::String)), } } } #[cfg(any(feature = "std", feature = "collections"))] impl Deserialize for String { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { deserializer.deserialize_string(StringVisitor) } } /////////////////////////////////////////////////////////////////////////////// struct OptionVisitor { marker: PhantomData, } impl< T: Deserialize, > Visitor for OptionVisitor { type Value = Option; #[inline] fn visit_unit(&mut self) -> Result, E> where E: Error, { Ok(None) } #[inline] fn visit_none(&mut self) -> Result, E> where E: Error, { Ok(None) } #[inline] fn visit_some(&mut self, deserializer: &mut D) -> Result, D::Error> where D: Deserializer, { Ok(Some(try!(Deserialize::deserialize(deserializer)))) } } impl Deserialize for Option where T: Deserialize { fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer, { deserializer.deserialize_option(OptionVisitor { marker: PhantomData }) } } /////////////////////////////////////////////////////////////////////////////// /// A visitor that produces a `PhantomData`. pub struct PhantomDataVisitor { marker: PhantomData, } impl Visitor for PhantomDataVisitor where T: Deserialize { type Value = PhantomData; #[inline] fn visit_unit(&mut self) -> Result, E> where E: Error, { Ok(PhantomData) } } impl Deserialize for PhantomData where T: Deserialize { fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer, { let visitor = PhantomDataVisitor { marker: PhantomData }; deserializer.deserialize_unit_struct("PhantomData", visitor) } } /////////////////////////////////////////////////////////////////////////////// macro_rules! seq_impl { ( $ty:ty, < $($constraints:ident),* >, $visitor_name:ident, $visitor:ident, $ctor:expr, $with_capacity:expr, $insert:expr ) => { /// A visitor that produces a sequence. pub struct $visitor_name { marker: PhantomData, } impl $visitor_name { /// Construct a new sequence visitor. pub fn new() -> Self { $visitor_name { marker: PhantomData, } } } impl Visitor for $visitor_name where T: $($constraints +)*, { type Value = $ty; #[inline] fn visit_unit(&mut self) -> Result<$ty, E> where E: Error, { Ok($ctor) } #[inline] fn visit_seq(&mut self, mut $visitor: V) -> Result<$ty, V::Error> where V: SeqVisitor, { let mut values = $with_capacity; while let Some(value) = try!($visitor.visit()) { $insert(&mut values, value); } try!($visitor.end()); Ok(values) } } impl Deserialize for $ty where T: $($constraints +)*, { fn deserialize(deserializer: &mut D) -> Result<$ty, D::Error> where D: Deserializer, { deserializer.deserialize_seq($visitor_name::new()) } } } } #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( BinaryHeap, , BinaryHeapVisitor, visitor, BinaryHeap::new(), BinaryHeap::with_capacity(visitor.size_hint().0), BinaryHeap::push); #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( BTreeSet, , BTreeSetVisitor, visitor, BTreeSet::new(), BTreeSet::new(), BTreeSet::insert); #[cfg(all(feature = "nightly", feature = "collections"))] seq_impl!( EnumSet, , EnumSetVisitor, visitor, EnumSet::new(), EnumSet::new(), EnumSet::insert); #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( LinkedList, , LinkedListVisitor, visitor, LinkedList::new(), LinkedList::new(), LinkedList::push_back); #[cfg(feature = "std")] seq_impl!( HashSet, , HashSetVisitor, visitor, HashSet::new(), HashSet::with_capacity(visitor.size_hint().0), HashSet::insert); #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( Vec, , VecVisitor, visitor, Vec::new(), Vec::with_capacity(visitor.size_hint().0), Vec::push); #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( VecDeque, , VecDequeVisitor, visitor, VecDeque::new(), VecDeque::with_capacity(visitor.size_hint().0), VecDeque::push_back); /////////////////////////////////////////////////////////////////////////////// struct ArrayVisitor0 { marker: PhantomData, } impl ArrayVisitor0 { /// Construct a `ArrayVisitor0`. pub fn new() -> Self { ArrayVisitor0 { marker: PhantomData, } } } impl Visitor for ArrayVisitor0 where T: Deserialize + Default { type Value = [T; 0]; #[inline] fn visit_unit(&mut self) -> Result<[T; 0], E> where E: Error, { Ok([T::default(); 0]) } #[inline] fn visit_seq(&mut self, mut visitor: V) -> Result<[T; 0], V::Error> where V: SeqVisitor, { try!(visitor.end()); Ok([T::default(); 0]) } } impl Deserialize for [T; 0] where T: Deserialize + Default { fn deserialize(deserializer: &mut D) -> Result<[T; 0], D::Error> where D: Deserializer, { deserializer.deserialize_seq(ArrayVisitor0::new()) } } macro_rules! array_impls { ($($visitor:ident, $len:expr => ($($name:ident),+),)+) => { $( struct $visitor { marker: PhantomData, } impl $visitor { /// Construct a `ArrayVisitor*`. pub fn new() -> Self { $visitor { marker: PhantomData } } } impl Visitor for $visitor where T: Deserialize { type Value = [T; $len]; #[inline] fn visit_seq(&mut self, mut visitor: V) -> Result<[T; $len], V::Error> where V: SeqVisitor, { $( let $name = match try!(visitor.visit()) { Some(val) => val, None => { return Err(Error::end_of_stream()); } }; )+; try!(visitor.end()); Ok([$($name,)+]) } } impl Deserialize for [T; $len] where T: Deserialize, { fn deserialize(deserializer: &mut D) -> Result<[T; $len], D::Error> where D: Deserializer, { deserializer.deserialize_fixed_size_array($len, $visitor::new()) } } )+ } } array_impls! { ArrayVisitor1, 1 => (a), ArrayVisitor2, 2 => (a, b), ArrayVisitor3, 3 => (a, b, c), ArrayVisitor4, 4 => (a, b, c, d), ArrayVisitor5, 5 => (a, b, c, d, e), ArrayVisitor6, 6 => (a, b, c, d, e, f), ArrayVisitor7, 7 => (a, b, c, d, e, f, g), ArrayVisitor8, 8 => (a, b, c, d, e, f, g, h), ArrayVisitor9, 9 => (a, b, c, d, e, f, g, h, i), ArrayVisitor10, 10 => (a, b, c, d, e, f, g, h, i, j), ArrayVisitor11, 11 => (a, b, c, d, e, f, g, h, i, j, k), ArrayVisitor12, 12 => (a, b, c, d, e, f, g, h, i, j, k, l), ArrayVisitor13, 13 => (a, b, c, d, e, f, g, h, i, j, k, l, m), ArrayVisitor14, 14 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n), ArrayVisitor15, 15 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o), ArrayVisitor16, 16 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p), ArrayVisitor17, 17 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q), ArrayVisitor18, 18 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r), ArrayVisitor19, 19 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s), ArrayVisitor20, 20 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ,t), ArrayVisitor21, 21 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u), ArrayVisitor22, 22 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v), ArrayVisitor23, 23 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w), ArrayVisitor24, 24 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x), ArrayVisitor25, 25 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y), ArrayVisitor26, 26 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z), ArrayVisitor27, 27 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa), ArrayVisitor28, 28 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab), ArrayVisitor29, 29 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac), ArrayVisitor30, 30 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad), ArrayVisitor31, 31 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae), ArrayVisitor32, 32 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af), } /////////////////////////////////////////////////////////////////////////////// macro_rules! tuple_impls { () => {}; ($($len:expr => $visitor:ident => ($($name:ident),+),)+) => { $( /// Construct a tuple visitor. pub struct $visitor<$($name,)+> { marker: PhantomData<($($name,)+)>, } impl< $($name: Deserialize,)+ > $visitor<$($name,)+> { /// Construct a `TupleVisitor*`. pub fn new() -> Self { $visitor { marker: PhantomData } } } impl< $($name: Deserialize,)+ > Visitor for $visitor<$($name,)+> { type Value = ($($name,)+); #[inline] #[allow(non_snake_case)] fn visit_seq(&mut self, mut visitor: V) -> Result<($($name,)+), V::Error> where V: SeqVisitor, { $( let $name = match try!(visitor.visit()) { Some(value) => value, None => { return Err(Error::end_of_stream()); } }; )+; try!(visitor.end()); Ok(($($name,)+)) } } impl< $($name: Deserialize),+ > Deserialize for ($($name,)+) { #[inline] fn deserialize(deserializer: &mut D) -> Result<($($name,)+), D::Error> where D: Deserializer, { deserializer.deserialize_tuple($len, $visitor::new()) } } )+ } } tuple_impls! { 1 => TupleVisitor1 => (T0), 2 => TupleVisitor2 => (T0, T1), 3 => TupleVisitor3 => (T0, T1, T2), 4 => TupleVisitor4 => (T0, T1, T2, T3), 5 => TupleVisitor5 => (T0, T1, T2, T3, T4), 6 => TupleVisitor6 => (T0, T1, T2, T3, T4, T5), 7 => TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6), 8 => TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7), 9 => TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8), 10 => TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9), 11 => TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), 12 => TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11), } /////////////////////////////////////////////////////////////////////////////// macro_rules! map_impl { ( $ty:ty, < $($constraints:ident),* >, $visitor_name:ident, $visitor:ident, $ctor:expr, $with_capacity:expr, $insert:expr ) => { /// A visitor that produces a map. pub struct $visitor_name { marker: PhantomData<$ty>, } impl $visitor_name { /// Construct a `MapVisitor*`. pub fn new() -> Self { $visitor_name { marker: PhantomData, } } } impl Visitor for $visitor_name where K: $($constraints +)*, V: Deserialize, { type Value = $ty; #[inline] fn visit_unit(&mut self) -> Result<$ty, E> where E: Error, { Ok($ctor) } #[inline] fn visit_map(&mut self, mut $visitor: Visitor) -> Result<$ty, Visitor::Error> where Visitor: MapVisitor, { let mut values = $with_capacity; while let Some((key, value)) = try!($visitor.visit()) { $insert(&mut values, key, value); } try!($visitor.end()); Ok(values) } } impl Deserialize for $ty where K: $($constraints +)*, V: Deserialize, { fn deserialize(deserializer: &mut D) -> Result<$ty, D::Error> where D: Deserializer, { deserializer.deserialize_map($visitor_name::new()) } } } } #[cfg(any(feature = "std", feature = "collections"))] map_impl!( BTreeMap, , BTreeMapVisitor, visitor, BTreeMap::new(), BTreeMap::new(), BTreeMap::insert); #[cfg(feature = "std")] map_impl!( HashMap, , HashMapVisitor, visitor, HashMap::new(), HashMap::with_capacity(visitor.size_hint().0), HashMap::insert); /////////////////////////////////////////////////////////////////////////////// #[cfg(all(feature = "nightly", feature = "std"))] impl Deserialize for net::IpAddr { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { let s = try!(String::deserialize(deserializer)); match s.parse() { Ok(s) => Ok(s), Err(err) => Err(D::Error::invalid_value(&err.to_string())), } } } #[cfg(feature = "std")] impl Deserialize for net::Ipv4Addr { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { let s = try!(String::deserialize(deserializer)); match s.parse() { Ok(s) => Ok(s), Err(err) => Err(D::Error::invalid_value(&err.to_string())), } } } #[cfg(feature = "std")] impl Deserialize for net::Ipv6Addr { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { let s = try!(String::deserialize(deserializer)); match s.parse() { Ok(s) => Ok(s), Err(err) => Err(D::Error::invalid_value(&err.to_string())), } } } /////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] impl Deserialize for net::SocketAddr { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { let s = try!(String::deserialize(deserializer)); match s.parse() { Ok(s) => Ok(s), Err(err) => Err(D::Error::invalid_value(&err.to_string())), } } } #[cfg(feature = "std")] impl Deserialize for net::SocketAddrV4 { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { let s = try!(String::deserialize(deserializer)); match s.parse() { Ok(s) => Ok(s), Err(err) => Err(D::Error::invalid_value(&err.to_string())), } } } #[cfg(feature = "std")] impl Deserialize for net::SocketAddrV6 { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { let s = try!(String::deserialize(deserializer)); match s.parse() { Ok(s) => Ok(s), Err(err) => Err(D::Error::invalid_value(&err.to_string())), } } } /////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] struct PathBufVisitor; #[cfg(feature = "std")] impl Visitor for PathBufVisitor { type Value = path::PathBuf; fn visit_str(&mut self, v: &str) -> Result where E: Error, { Ok(From::from(v)) } fn visit_string(&mut self, v: String) -> Result where E: Error, { self.visit_str(&v) } } #[cfg(feature = "std")] impl Deserialize for path::PathBuf { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { deserializer.deserialize_string(PathBufVisitor) } } /////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "alloc"))] impl Deserialize for Box { fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer, { let val = try!(Deserialize::deserialize(deserializer)); Ok(Box::new(val)) } } #[cfg(any(feature = "std", feature = "collections"))] impl Deserialize for Box<[T]> { fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer, { let v: Vec = try!(Deserialize::deserialize(deserializer)); Ok(v.into_boxed_slice()) } } #[cfg(any(feature = "std", feature = "alloc"))] impl Deserialize for Arc { fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer, { let val = try!(Deserialize::deserialize(deserializer)); Ok(Arc::new(val)) } } #[cfg(any(feature = "std", feature = "alloc"))] impl Deserialize for Rc { fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer, { let val = try!(Deserialize::deserialize(deserializer)); Ok(Rc::new(val)) } } #[cfg(any(feature = "std", feature = "collections"))] impl<'a, T: ?Sized> Deserialize for Cow<'a, T> where T: ToOwned, T::Owned: Deserialize, { #[inline] fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer, { let val = try!(Deserialize::deserialize(deserializer)); Ok(Cow::Owned(val)) } } /////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "nightly")] impl Deserialize for NonZero where T: Deserialize + PartialEq + Zeroable + Zero { fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer { let value = try!(Deserialize::deserialize(deserializer)); if value == Zero::zero() { return Err(Error::invalid_value("expected a non-zero value")) } unsafe { Ok(NonZero::new(value)) } } } /////////////////////////////////////////////////////////////////////////////// impl Deserialize for Result where T: Deserialize, E: Deserialize { fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer { enum Field { Ok, Err, } impl Deserialize for Field { #[inline] fn deserialize(deserializer: &mut D) -> Result where D: Deserializer { struct FieldVisitor; impl ::de::Visitor for FieldVisitor { type Value = Field; #[cfg(any(feature = "std", feature = "collections"))] fn visit_usize(&mut self, value: usize) -> Result where E: Error { #[cfg(feature = "collections")] use collections::string::ToString; match value { 0 => Ok(Field::Ok), 1 => Ok(Field::Err), _ => Err(Error::unknown_field(&value.to_string())), } } #[cfg(all(not(feature = "std"), not(feature = "collections")))] fn visit_usize(&mut self, value: usize) -> Result where E: Error { match value { 0 => Ok(Field::Ok), 1 => Ok(Field::Err), _ => Err(Error::unknown_field("some number")), } } fn visit_str(&mut self, value: &str) -> Result where E: Error { match value { "Ok" => Ok(Field::Ok), "Err" => Ok(Field::Err), _ => Err(Error::unknown_field(value)), } } fn visit_bytes(&mut self, value: &[u8]) -> Result where E: Error { match value { b"Ok" => Ok(Field::Ok), b"Err" => Ok(Field::Err), _ => { match str::from_utf8(value) { Ok(value) => Err(Error::unknown_field(value)), Err(_) => Err(Error::invalid_type(Type::String)), } } } } } deserializer.deserialize(FieldVisitor) } } struct Visitor(PhantomData>); impl EnumVisitor for Visitor where T: Deserialize, E: Deserialize { type Value = Result; fn visit(&mut self, mut visitor: V) -> Result, V::Error> where V: VariantVisitor { match try!(visitor.visit_variant()) { Field::Ok => { let value = try!(visitor.visit_newtype()); Ok(Ok(value)) } Field::Err => { let value = try!(visitor.visit_newtype()); Ok(Err(value)) } } } } const VARIANTS: &'static [&'static str] = &["Ok", "Err"]; deserializer.deserialize_enum("Result", VARIANTS, Visitor(PhantomData)) } } /////////////////////////////////////////////////////////////////////////////// /// A target for deserializers that want to ignore data. Implements /// Deserialize and silently eats data given to it. pub struct IgnoredAny; impl Deserialize for IgnoredAny { #[inline] fn deserialize(deserializer: &mut D) -> Result where D: Deserializer, { struct IgnoredAnyVisitor; impl Visitor for IgnoredAnyVisitor { type Value = IgnoredAny; #[inline] fn visit_bool(&mut self, _: bool) -> Result { Ok(IgnoredAny) } #[inline] fn visit_i64(&mut self, _: i64) -> Result { Ok(IgnoredAny) } #[inline] fn visit_u64(&mut self, _: u64) -> Result { Ok(IgnoredAny) } #[inline] fn visit_f64(&mut self, _: f64) -> Result { Ok(IgnoredAny) } #[inline] fn visit_str(&mut self, _: &str) -> Result where E: Error, { Ok(IgnoredAny) } #[inline] fn visit_none(&mut self) -> Result { Ok(IgnoredAny) } #[inline] fn visit_some(&mut self, _: &mut D) -> Result where D: Deserializer, { Ok(IgnoredAny) } #[inline] fn visit_newtype_struct(&mut self, _: &mut D) -> Result where D: Deserializer, { Ok(IgnoredAny) } #[inline] fn visit_unit(&mut self) -> Result { Ok(IgnoredAny) } #[inline] fn visit_seq(&mut self, mut visitor: V) -> Result where V: SeqVisitor, { while let Some(_) = try!(visitor.visit::()) { // Gobble } try!(visitor.end()); Ok(IgnoredAny) } #[inline] fn visit_map(&mut self, mut visitor: V) -> Result where V: MapVisitor, { while let Some((_, _)) = try!(visitor.visit::()) { // Gobble } try!(visitor.end()); Ok(IgnoredAny) } #[inline] fn visit_bytes(&mut self, _: &[u8]) -> Result where E: Error, { Ok(IgnoredAny) } } // TODO maybe not necessary with impl specialization deserializer.deserialize_ignored_any(IgnoredAnyVisitor) } }