use crate::{formats::*, prelude::*}; #[cfg(feature = "indexmap_1")] use indexmap_1::{IndexMap, IndexSet}; /////////////////////////////////////////////////////////////////////////////// // Helper macro used internally #[cfg(feature = "alloc")] type BoxedSlice = Box<[T]>; macro_rules! foreach_map { ($m:ident) => { #[cfg(feature = "alloc")] $m!(BTreeMap); #[cfg(feature = "std")] $m!(HashMap); #[cfg(all(feature = "std", feature = "indexmap_1"))] $m!(IndexMap); }; } pub(crate) use foreach_map; macro_rules! foreach_map_create { ($m:ident) => { #[cfg(feature = "alloc")] $m!(BTreeMap, (|_size| BTreeMap::new())); #[cfg(feature = "std")] $m!(HashMap, (|size| HashMap::with_capacity_and_hasher(size, Default::default()))); #[cfg(feature = "indexmap_1")] $m!(IndexMap, (|size| IndexMap::with_capacity_and_hasher(size, Default::default()))); } } pub(crate) use foreach_map_create; macro_rules! foreach_set { ($m:ident) => { #[cfg(feature = "alloc")] $m!(BTreeSet<(K, V): Ord>); #[cfg(feature = "std")] $m!(HashSet<(K, V): Eq + Hash>); #[cfg(all(feature = "std", feature = "indexmap_1"))] $m!(IndexSet<(K, V): Eq + Hash>); } } pub(crate) use foreach_set; macro_rules! foreach_set_create { ($m:ident) => { #[cfg(feature = "alloc")] $m!(BTreeSet, (|_| BTreeSet::new()), insert); #[cfg(feature = "std")] $m!( HashSet, (|size| HashSet::with_capacity_and_hasher(size, S::default())), insert ); #[cfg(feature = "indexmap_1")] $m!( IndexSet, (|size| IndexSet::with_capacity_and_hasher(size, S::default())), insert ); } } pub(crate) use foreach_set_create; macro_rules! foreach_seq { ($m:ident) => { foreach_set!($m); #[cfg(feature = "alloc")] $m!(BinaryHeap<(K, V): Ord>); #[cfg(feature = "alloc")] $m!(LinkedList<(K, V)>); #[cfg(feature = "alloc")] $m!(Vec<(K, V)>); #[cfg(feature = "alloc")] $m!(VecDeque<(K, V)>); } } pub(crate) use foreach_seq; macro_rules! foreach_seq_create { ($m:ident) => { foreach_set_create!($m); #[cfg(feature = "alloc")] $m!( BinaryHeap, (|size| BinaryHeap::with_capacity(size)), push ); #[cfg(feature = "alloc")] $m!(BoxedSlice, (|size| Vec::with_capacity(size)), push); #[cfg(feature = "alloc")] $m!(LinkedList, (|_| LinkedList::new()), push_back); #[cfg(feature = "alloc")] $m!(Vec, (|size| Vec::with_capacity(size)), push); #[cfg(feature = "alloc")] $m!( VecDeque, (|size| VecDeque::with_capacity(size)), push_back ); }; } pub(crate) use foreach_seq_create; /////////////////////////////////////////////////////////////////////////////// // region: Simple Wrapper types (e.g., Box, Option) #[cfg(feature = "alloc")] impl<'de, T, U> DeserializeAs<'de, Box> for Box where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Ok(Box::new( DeserializeAsWrap::::deserialize(deserializer)?.into_inner(), )) } } impl<'de, T, U> DeserializeAs<'de, Option> for Option where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { struct OptionVisitor(PhantomData<(T, U)>); impl<'de, T, U> Visitor<'de> for OptionVisitor where U: DeserializeAs<'de, T>, { type Value = Option; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("option") } #[inline] fn visit_unit(self) -> Result where E: DeError, { Ok(None) } #[inline] fn visit_none(self) -> Result where E: DeError, { Ok(None) } #[inline] fn visit_some(self, deserializer: D) -> Result where D: Deserializer<'de>, { U::deserialize_as(deserializer).map(Some) } } deserializer.deserialize_option(OptionVisitor::(PhantomData)) } } #[cfg(feature = "alloc")] impl<'de, T, U> DeserializeAs<'de, Rc> for Rc where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Ok(Rc::new( DeserializeAsWrap::::deserialize(deserializer)?.into_inner(), )) } } #[cfg(feature = "alloc")] impl<'de, T, U> DeserializeAs<'de, RcWeak> for RcWeak where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { DeserializeAsWrap::>, Option>>::deserialize(deserializer)?; Ok(RcWeak::new()) } } #[cfg(all(feature = "alloc", target_has_atomic = "ptr"))] impl<'de, T, U> DeserializeAs<'de, Arc> for Arc where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Ok(Arc::new( DeserializeAsWrap::::deserialize(deserializer)?.into_inner(), )) } } #[cfg(all(feature = "alloc", target_has_atomic = "ptr"))] impl<'de, T, U> DeserializeAs<'de, ArcWeak> for ArcWeak where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { DeserializeAsWrap::>, Option>>::deserialize(deserializer)?; Ok(ArcWeak::new()) } } impl<'de, T, U> DeserializeAs<'de, Cell> for Cell where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Ok(Cell::new( DeserializeAsWrap::::deserialize(deserializer)?.into_inner(), )) } } impl<'de, T, U> DeserializeAs<'de, RefCell> for RefCell where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Ok(RefCell::new( DeserializeAsWrap::::deserialize(deserializer)?.into_inner(), )) } } #[cfg(feature = "std")] impl<'de, T, U> DeserializeAs<'de, Mutex> for Mutex where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Ok(Mutex::new( DeserializeAsWrap::::deserialize(deserializer)?.into_inner(), )) } } #[cfg(feature = "std")] impl<'de, T, U> DeserializeAs<'de, RwLock> for RwLock where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Ok(RwLock::new( DeserializeAsWrap::::deserialize(deserializer)?.into_inner(), )) } } impl<'de, T, TAs, E, EAs> DeserializeAs<'de, Result> for Result where TAs: DeserializeAs<'de, T>, EAs: DeserializeAs<'de, E>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Ok( match Result::, DeserializeAsWrap>::deserialize( deserializer, )? { Ok(value) => Ok(value.into_inner()), Err(err) => Err(err.into_inner()), }, ) } } impl<'de, T, As, const N: usize> DeserializeAs<'de, [T; N]> for [As; N] where As: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result<[T; N], D::Error> where D: Deserializer<'de>, { struct ArrayVisitor(PhantomData); impl<'de, T, As, const M: usize> Visitor<'de> for ArrayVisitor, M> where As: DeserializeAs<'de, T>, { type Value = [T; M]; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_fmt(format_args!("an array of size {M}")) } fn visit_seq(self, seq: A) -> Result where A: SeqAccess<'de>, { utils::array_from_iterator( utils::SeqIter::new(seq).map( |res: Result, A::Error>| { res.map(|t| t.into_inner()) }, ), &self, ) } } deserializer.deserialize_tuple(N, ArrayVisitor::, N>(PhantomData)) } } // endregion /////////////////////////////////////////////////////////////////////////////// // region: Collection Types (e.g., Maps, Sets, Vec) #[cfg(feature = "alloc")] macro_rules! seq_impl { ( $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)* )* >, $with_capacity:expr, $append:ident ) => { // Fix for clippy regression in macros on stable // The bug no longer exists on nightly // https://github.com/rust-lang/rust-clippy/issues/7768 #[allow(clippy::semicolon_if_nothing_returned)] impl<'de, T, U $(, $typaram)*> DeserializeAs<'de, $ty> for $ty where U: DeserializeAs<'de, T>, $(T: $tbound1 $(+ $tbound2)*,)* $($typaram: $bound1 $(+ $bound2)*),* { fn deserialize_as(deserializer: D) -> Result<$ty, D::Error> where D: Deserializer<'de>, { struct SeqVisitor { marker: PhantomData<(T, U $(, $typaram)*)>, } impl<'de, T, U $(, $typaram)*> Visitor<'de> for SeqVisitor where U: DeserializeAs<'de, T>, $(T: $tbound1 $(+ $tbound2)*,)* $($typaram: $bound1 $(+ $bound2)*),* { type Value = $ty; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a sequence") } fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, { let mut values = ($with_capacity)(utils::size_hint_cautious(seq.size_hint())); while let Some(value) = seq .next_element()? .map(|v: DeserializeAsWrap| v.into_inner()) { values.$append(value); } Ok(values.into()) } } let visitor = SeqVisitor:: { marker: PhantomData, }; deserializer.deserialize_seq(visitor) } } }; } foreach_seq_create!(seq_impl); #[cfg(feature = "alloc")] macro_rules! map_impl { ( $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, $with_capacity:expr ) => { // Fix for clippy regression in macros on stable // The bug no longer exists on nightly // https://github.com/rust-lang/rust-clippy/issues/7768 #[allow(clippy::semicolon_if_nothing_returned)] impl<'de, K, V, KU, VU $(, $typaram)*> DeserializeAs<'de, $ty> for $ty where KU: DeserializeAs<'de, K>, VU: DeserializeAs<'de, V>, $(K: $kbound1 $(+ $kbound2)*,)* $($typaram: $bound1 $(+ $bound2)*),* { fn deserialize_as(deserializer: D) -> Result<$ty, D::Error> where D: Deserializer<'de>, { struct MapVisitor(PhantomData<(K, V, KU, VU $(, $typaram)*)>); impl<'de, K, V, KU, VU $(, $typaram)*> Visitor<'de> for MapVisitor where KU: DeserializeAs<'de, K>, VU: DeserializeAs<'de, V>, $(K: $kbound1 $(+ $kbound2)*,)* $($typaram: $bound1 $(+ $bound2)*),* { type Value = $ty; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a map") } #[inline] fn visit_map(self, mut map: A) -> Result where A: MapAccess<'de>, { let mut values = ($with_capacity)(utils::size_hint_cautious(map.size_hint())); while let Some((key, value)) = (map.next_entry())?.map(|(k, v): (DeserializeAsWrap::, DeserializeAsWrap::)| (k.into_inner(), v.into_inner())) { values.insert(key, value); } Ok(values) } } let visitor = MapVisitor:: (PhantomData); deserializer.deserialize_map(visitor) } } } } foreach_map_create!(map_impl); macro_rules! tuple_impl { ($len:literal $($n:tt $t:ident $tas:ident)+) => { impl<'de, $($t, $tas,)+> DeserializeAs<'de, ($($t,)+)> for ($($tas,)+) where $($tas: DeserializeAs<'de, $t>,)+ { fn deserialize_as(deserializer: D) -> Result<($($t,)+), D::Error> where D: Deserializer<'de>, { struct TupleVisitor<$($t,)+>(PhantomData<($($t,)+)>); impl<'de, $($t, $tas,)+> Visitor<'de> for TupleVisitor<$(DeserializeAsWrap<$t, $tas>,)+> where $($tas: DeserializeAs<'de, $t>,)+ { type Value = ($($t,)+); fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str(concat!("a tuple of size ", $len)) } #[allow(non_snake_case)] fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, { $( let $t: DeserializeAsWrap<$t, $tas> = match seq.next_element()? { Some(value) => value, None => return Err(DeError::invalid_length($n, &self)), }; )+ Ok(($($t.into_inner(),)+)) } } deserializer.deserialize_tuple( $len, TupleVisitor::<$(DeserializeAsWrap<$t, $tas>,)+>(PhantomData), ) } } }; } tuple_impl!(1 0 T0 As0); tuple_impl!(2 0 T0 As0 1 T1 As1); tuple_impl!(3 0 T0 As0 1 T1 As1 2 T2 As2); tuple_impl!(4 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3); tuple_impl!(5 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4); tuple_impl!(6 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5); tuple_impl!(7 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6); tuple_impl!(8 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7); tuple_impl!(9 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8); tuple_impl!(10 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9); tuple_impl!(11 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10); tuple_impl!(12 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11); tuple_impl!(13 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12); tuple_impl!(14 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12 13 T13 As13); tuple_impl!(15 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12 13 T13 As13 14 T14 As14); tuple_impl!(16 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12 13 T13 As13 14 T14 As14 15 T15 As15); #[cfg(feature = "alloc")] macro_rules! map_as_tuple_seq_intern { ($tyorig:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, $ty:ident <(KAs, VAs)>) => { impl<'de, K, KAs, V, VAs> DeserializeAs<'de, $tyorig> for $ty<(KAs, VAs)> where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, $(K: $kbound1 $(+ $kbound2)*,)* { fn deserialize_as(deserializer: D) -> Result<$tyorig, D::Error> where D: Deserializer<'de>, { struct SeqVisitor { marker: PhantomData<(K, KAs, V, VAs)>, } impl<'de, K, KAs, V, VAs> Visitor<'de> for SeqVisitor where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, $(K: $kbound1 $(+ $kbound2)*,)* { type Value = $tyorig; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a sequence") } #[inline] fn visit_seq(self, access: A) -> Result where A: SeqAccess<'de>, { let iter = utils::SeqIter::new(access); iter.map(|res| { res.map( |(k, v): (DeserializeAsWrap, DeserializeAsWrap)| { (k.into_inner(), v.into_inner()) }, ) }) .collect() } } let visitor = SeqVisitor:: { marker: PhantomData, }; deserializer.deserialize_seq(visitor) } } }; } #[cfg(feature = "alloc")] macro_rules! map_as_tuple_seq { ($tyorig:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >) => { map_as_tuple_seq_intern!($tyorig < K $(: $kbound1 $(+ $kbound2)*)* , V $(, $typaram : $bound1 $(+ $bound2)*)* > , Seq<(KAs, VAs)>); #[cfg(feature = "alloc")] map_as_tuple_seq_intern!($tyorig < K $(: $kbound1 $(+ $kbound2)*)* , V $(, $typaram : $bound1 $(+ $bound2)*)* >, Vec<(KAs, VAs)>); } } foreach_map!(map_as_tuple_seq); #[cfg(feature = "alloc")] macro_rules! tuple_seq_as_map_impl_intern { ($tyorig:ident < (K, V) $(: $($bound:ident $(+)?)+)?>, $ty:ident ) => { #[allow(clippy::implicit_hasher)] impl<'de, K, KAs, V, VAs> DeserializeAs<'de, $tyorig < (K, V) >> for $ty where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, (K, V): $($($bound +)*)*, { fn deserialize_as(deserializer: D) -> Result<$tyorig < (K, V) >, D::Error> where D: Deserializer<'de>, { struct MapVisitor { marker: PhantomData<(K, KAs, V, VAs)>, } impl<'de, K, KAs, V, VAs> Visitor<'de> for MapVisitor where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, (K, V): $($($bound +)*)*, { type Value = $tyorig < (K, V) >; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a map") } #[inline] fn visit_map(self, access: A) -> Result where A: MapAccess<'de>, { let iter = utils::MapIter::new(access); iter.map(|res| { res.map( |(k, v): (DeserializeAsWrap, DeserializeAsWrap)| { (k.into_inner(), v.into_inner()) }, ) }) .collect() } } let visitor = MapVisitor:: { marker: PhantomData, }; deserializer.deserialize_map(visitor) } } } } #[cfg(feature = "alloc")] macro_rules! tuple_seq_as_map_impl { ($tyorig:ident < (K, V) $(: $($bound:ident $(+)?)+)?>) => { tuple_seq_as_map_impl_intern!($tyorig < (K, V) $(: $($bound +)+)? >, Map); #[cfg(feature = "alloc")] tuple_seq_as_map_impl_intern!($tyorig < (K, V) $(: $($bound +)+)? >, BTreeMap); #[cfg(feature = "std")] tuple_seq_as_map_impl_intern!($tyorig < (K, V) $(: $($bound +)+)? >, HashMap); } } foreach_seq!(tuple_seq_as_map_impl); // Option does not implement FromIterator directly, so we need a different implementation #[cfg(feature = "alloc")] macro_rules! tuple_seq_as_map_option_impl { ($ty:ident) => { #[allow(clippy::implicit_hasher)] impl<'de, K, KAs, V, VAs> DeserializeAs<'de, Option<(K, V)>> for $ty where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { struct MapVisitor { marker: PhantomData<(K, KAs, V, VAs)>, } impl<'de, K, KAs, V, VAs> Visitor<'de> for MapVisitor where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, { type Value = Option<(K, V)>; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a map of size 1") } #[inline] fn visit_map(self, access: A) -> Result where A: MapAccess<'de>, { let iter = utils::MapIter::new(access); iter.map(|res| { res.map( |(k, v): (DeserializeAsWrap, DeserializeAsWrap)| { (k.into_inner(), v.into_inner()) }, ) }) .next() .transpose() } } let visitor = MapVisitor:: { marker: PhantomData, }; deserializer.deserialize_map(visitor) } } }; } #[cfg(feature = "alloc")] tuple_seq_as_map_option_impl!(BTreeMap); #[cfg(feature = "std")] tuple_seq_as_map_option_impl!(HashMap); macro_rules! tuple_seq_as_map_arr { ($ty:ident ) => { #[allow(clippy::implicit_hasher)] impl<'de, K, KAs, V, VAs, const N: usize> DeserializeAs<'de, [(K, V); N]> for $ty where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, { fn deserialize_as(deserializer: D) -> Result<[(K, V); N], D::Error> where D: Deserializer<'de>, { struct MapVisitor { marker: PhantomData<(K, KAs, V, VAs)>, } impl<'de, K, KAs, V, VAs, const M: usize> Visitor<'de> for MapVisitor where KAs: DeserializeAs<'de, K>, VAs: DeserializeAs<'de, V>, { type Value = [(K, V); M]; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_fmt(format_args!("a map of length {}", M)) } fn visit_map(self, access: A) -> Result where A: MapAccess<'de>, { utils::array_from_iterator(utils::MapIter::new(access).map( |res: Result<(DeserializeAsWrap, DeserializeAsWrap), A::Error>| { res.map(|(k, v)| (k.into_inner(), v.into_inner())) } ), &self) } } let visitor = MapVisitor:: { marker: PhantomData, }; deserializer.deserialize_map(visitor) } } } } tuple_seq_as_map_arr!(Map); #[cfg(feature = "alloc")] tuple_seq_as_map_arr!(BTreeMap); #[cfg(feature = "std")] tuple_seq_as_map_arr!(HashMap); // endregion /////////////////////////////////////////////////////////////////////////////// // region: Conversion types which cause different serialization behavior impl<'de, T: Deserialize<'de>> DeserializeAs<'de, T> for Same { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { T::deserialize(deserializer) } } impl<'de, T> DeserializeAs<'de, T> for DisplayFromStr where T: FromStr, T::Err: Display, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { struct Helper(PhantomData); impl<'de, S> Visitor<'de> for Helper where S: FromStr, ::Err: Display, { type Value = S; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!(formatter, "a string") } fn visit_str(self, value: &str) -> Result where E: DeError, { value.parse::().map_err(DeError::custom) } } deserializer.deserialize_str(Helper(PhantomData)) } } #[cfg(feature = "alloc")] impl<'de, T, U> DeserializeAs<'de, Vec> for VecSkipError where U: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { enum GoodOrError { Good(T), // Only here to consume the TAs generic Error(PhantomData), } impl<'de, T, TAs> Deserialize<'de> for GoodOrError where TAs: DeserializeAs<'de, T>, { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { let is_hr = deserializer.is_human_readable(); let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?; Ok( match >::deserialize( content::de::ContentDeserializer::::new(content, is_hr), ) { Ok(elem) => GoodOrError::Good(elem.into_inner()), Err(_) => GoodOrError::Error(PhantomData), }, ) } } struct SeqVisitor { marker: PhantomData, marker2: PhantomData, } impl<'de, T, TAs> Visitor<'de> for SeqVisitor where TAs: DeserializeAs<'de, T>, { type Value = Vec; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a sequence") } fn visit_seq(self, seq: A) -> Result where A: SeqAccess<'de>, { utils::SeqIter::new(seq) .filter_map(|res: Result, A::Error>| match res { Ok(GoodOrError::Good(value)) => Some(Ok(value)), Ok(GoodOrError::Error(_)) => None, Err(err) => Some(Err(err)), }) .collect() } } let visitor = SeqVisitor:: { marker: PhantomData, marker2: PhantomData, }; deserializer.deserialize_seq(visitor) } } impl<'de, Str> DeserializeAs<'de, Option> for NoneAsEmptyString where Str: FromStr, Str::Err: Display, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { struct OptionStringEmptyNone(PhantomData); impl<'de, S> Visitor<'de> for OptionStringEmptyNone where S: FromStr, S::Err: Display, { type Value = Option; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a string") } fn visit_str(self, value: &str) -> Result where E: DeError, { match value { "" => Ok(None), v => S::from_str(v).map(Some).map_err(DeError::custom), } } // handles the `null` case fn visit_unit(self) -> Result where E: DeError, { Ok(None) } } deserializer.deserialize_any(OptionStringEmptyNone(PhantomData)) } } #[cfg(feature = "alloc")] impl<'de, T, TAs> DeserializeAs<'de, T> for DefaultOnError where TAs: DeserializeAs<'de, T>, T: Default, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { let is_hr = deserializer.is_human_readable(); let content: content::de::Content<'de> = match Deserialize::deserialize(deserializer) { Ok(content) => content, Err(_) => return Ok(Default::default()), }; Ok( match >::deserialize(content::de::ContentDeserializer::< D::Error, >::new(content, is_hr)) { Ok(elem) => elem.into_inner(), Err(_) => Default::default(), }, ) } } #[cfg(feature = "alloc")] impl<'de> DeserializeAs<'de, Vec> for BytesOrString { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { struct BytesOrStringVisitor; impl<'de> Visitor<'de> for BytesOrStringVisitor { type Value = Vec; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a list of bytes or a string") } fn visit_bytes(self, v: &[u8]) -> Result { Ok(v.to_vec()) } #[cfg(feature = "alloc")] fn visit_byte_buf(self, v: Vec) -> Result { Ok(v) } fn visit_str(self, v: &str) -> Result { Ok(v.as_bytes().to_vec()) } #[cfg(feature = "alloc")] fn visit_string(self, v: String) -> Result { Ok(v.into_bytes()) } fn visit_seq(self, seq: A) -> Result where A: SeqAccess<'de>, { utils::SeqIter::new(seq).collect() } } deserializer.deserialize_any(BytesOrStringVisitor) } } impl<'de, SEPARATOR, I, T> DeserializeAs<'de, I> for StringWithSeparator where SEPARATOR: Separator, I: FromIterator, T: FromStr, T::Err: Display, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { struct Helper(PhantomData<(SEPARATOR, I, T)>); impl<'de, SEPARATOR, I, T> Visitor<'de> for Helper where SEPARATOR: Separator, I: FromIterator, T: FromStr, T::Err: Display, { type Value = I; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!(formatter, "a string") } fn visit_str(self, value: &str) -> Result where E: DeError, { if value.is_empty() { Ok(None.into_iter().collect()) } else { value .split(SEPARATOR::separator()) .map(FromStr::from_str) .collect::>() .map_err(DeError::custom) } } } deserializer.deserialize_str(Helper::(PhantomData)) } } #[cfg(feature = "std")] macro_rules! use_signed_duration { ( $main_trait:ident $internal_trait:ident => { $ty:ty; $converter:ident => $({ $format:ty, $strictness:ty => $($tbound:ident: $bound:ident $(,)?)* })* } ) => { $( impl<'de, $($tbound,)*> DeserializeAs<'de, $ty> for $main_trait<$format, $strictness> where $($tbound: $bound,)* { fn deserialize_as(deserializer: D) -> Result<$ty, D::Error> where D: Deserializer<'de>, { let dur: DurationSigned = $internal_trait::<$format, $strictness>::deserialize_as(deserializer)?; dur.$converter::() } } )* }; ( $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt ) => { $( use_signed_duration!($main_trait $internal_trait => $rest); )+ }; } #[cfg(feature = "std")] use_signed_duration!( DurationSeconds DurationSeconds, DurationMilliSeconds DurationMilliSeconds, DurationMicroSeconds DurationMicroSeconds, DurationNanoSeconds DurationNanoSeconds, => { Duration; to_std_duration => {u64, Strict =>} {f64, Strict =>} {String, Strict =>} {FORMAT, Flexible => FORMAT: Format} } ); #[cfg(feature = "std")] use_signed_duration!( DurationSecondsWithFrac DurationSecondsWithFrac, DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac, DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac, DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac, => { Duration; to_std_duration => {f64, Strict =>} {String, Strict =>} {FORMAT, Flexible => FORMAT: Format} } ); #[cfg(feature = "std")] use_signed_duration!( TimestampSeconds DurationSeconds, TimestampMilliSeconds DurationMilliSeconds, TimestampMicroSeconds DurationMicroSeconds, TimestampNanoSeconds DurationNanoSeconds, => { SystemTime; to_system_time => {i64, Strict =>} {f64, Strict =>} {String, Strict =>} {FORMAT, Flexible => FORMAT: Format} } ); #[cfg(feature = "std")] use_signed_duration!( TimestampSecondsWithFrac DurationSecondsWithFrac, TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac, TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac, TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac, => { SystemTime; to_system_time => {f64, Strict =>} {String, Strict =>} {FORMAT, Flexible => FORMAT: Format} } ); impl<'de, T, U> DeserializeAs<'de, T> for DefaultOnNull where U: DeserializeAs<'de, T>, T: Default, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { Ok(Option::::deserialize_as(deserializer)?.unwrap_or_default()) } } impl<'de> DeserializeAs<'de, &'de [u8]> for Bytes { fn deserialize_as(deserializer: D) -> Result<&'de [u8], D::Error> where D: Deserializer<'de>, { <&'de [u8]>::deserialize(deserializer) } } // serde_bytes implementation for ByteBuf // https://github.com/serde-rs/bytes/blob/cbae606b9dc225fc094b031cc84eac9493da2058/src/bytebuf.rs#L196 // // Implements: // * visit_seq // * visit_bytes // * visit_byte_buf // * visit_str // * visit_string #[cfg(feature = "alloc")] impl<'de> DeserializeAs<'de, Vec> for Bytes { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { struct VecVisitor; impl<'de> Visitor<'de> for VecVisitor { type Value = Vec; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a byte array") } fn visit_seq(self, seq: A) -> Result where A: SeqAccess<'de>, { utils::SeqIter::new(seq).collect::>() } fn visit_bytes(self, v: &[u8]) -> Result where E: DeError, { Ok(v.to_vec()) } fn visit_byte_buf(self, v: Vec) -> Result where E: DeError, { Ok(v) } fn visit_str(self, v: &str) -> Result where E: DeError, { Ok(v.as_bytes().to_vec()) } fn visit_string(self, v: String) -> Result where E: DeError, { Ok(v.into_bytes()) } } deserializer.deserialize_byte_buf(VecVisitor) } } #[cfg(feature = "alloc")] impl<'de> DeserializeAs<'de, Box<[u8]>> for Bytes { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { >>::deserialize_as(deserializer) .map(|vec| vec.into_boxed_slice()) } } // serde_bytes implementation for Cow<'a, [u8]> // https://github.com/serde-rs/bytes/blob/cbae606b9dc225fc094b031cc84eac9493da2058/src/de.rs#L77 // // Implements: // * visit_borrowed_bytes // * visit_borrowed_str // * visit_bytes // * visit_str // * visit_byte_buf // * visit_string // * visit_seq #[cfg(feature = "alloc")] impl<'de> DeserializeAs<'de, Cow<'de, [u8]>> for Bytes { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { struct CowVisitor; impl<'de> Visitor<'de> for CowVisitor { type Value = Cow<'de, [u8]>; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a byte array") } fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result where E: DeError, { Ok(Cow::Borrowed(v)) } fn visit_borrowed_str(self, v: &'de str) -> Result where E: DeError, { Ok(Cow::Borrowed(v.as_bytes())) } fn visit_bytes(self, v: &[u8]) -> Result where E: DeError, { Ok(Cow::Owned(v.to_vec())) } fn visit_str(self, v: &str) -> Result where E: DeError, { Ok(Cow::Owned(v.as_bytes().to_vec())) } fn visit_byte_buf(self, v: Vec) -> Result where E: DeError, { Ok(Cow::Owned(v)) } fn visit_string(self, v: String) -> Result where E: DeError, { Ok(Cow::Owned(v.into_bytes())) } fn visit_seq(self, seq: V) -> Result where V: SeqAccess<'de>, { Ok(Cow::Owned( utils::SeqIter::new(seq).collect::>()?, )) } } deserializer.deserialize_bytes(CowVisitor) } } impl<'de, const N: usize> DeserializeAs<'de, [u8; N]> for Bytes { fn deserialize_as(deserializer: D) -> Result<[u8; N], D::Error> where D: Deserializer<'de>, { struct ArrayVisitor; impl<'de, const M: usize> Visitor<'de> for ArrayVisitor { type Value = [u8; M]; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_fmt(format_args!("an byte array of size {M}")) } fn visit_seq(self, seq: A) -> Result where A: SeqAccess<'de>, { utils::array_from_iterator(utils::SeqIter::new(seq), &self) } fn visit_bytes(self, v: &[u8]) -> Result where E: DeError, { v.try_into() .map_err(|_| DeError::invalid_length(v.len(), &self)) } fn visit_str(self, v: &str) -> Result where E: DeError, { v.as_bytes() .try_into() .map_err(|_| DeError::invalid_length(v.len(), &self)) } } deserializer.deserialize_bytes(ArrayVisitor::) } } impl<'de, const N: usize> DeserializeAs<'de, &'de [u8; N]> for Bytes { fn deserialize_as(deserializer: D) -> Result<&'de [u8; N], D::Error> where D: Deserializer<'de>, { struct ArrayVisitor; impl<'de, const M: usize> Visitor<'de> for ArrayVisitor { type Value = &'de [u8; M]; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_fmt(format_args!("a borrowed byte array of size {M}")) } fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result where E: DeError, { v.try_into() .map_err(|_| DeError::invalid_length(v.len(), &self)) } fn visit_borrowed_str(self, v: &'de str) -> Result where E: DeError, { v.as_bytes() .try_into() .map_err(|_| DeError::invalid_length(v.len(), &self)) } } deserializer.deserialize_bytes(ArrayVisitor::) } } #[cfg(feature = "alloc")] impl<'de, const N: usize> DeserializeAs<'de, Cow<'de, [u8; N]>> for Bytes { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { struct CowVisitor; impl<'de, const M: usize> Visitor<'de> for CowVisitor { type Value = Cow<'de, [u8; M]>; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a byte array") } fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result where E: DeError, { Ok(Cow::Borrowed( v.try_into() .map_err(|_| DeError::invalid_length(v.len(), &self))?, )) } fn visit_borrowed_str(self, v: &'de str) -> Result where E: DeError, { Ok(Cow::Borrowed( v.as_bytes() .try_into() .map_err(|_| DeError::invalid_length(v.len(), &self))?, )) } fn visit_bytes(self, v: &[u8]) -> Result where E: DeError, { Ok(Cow::Owned( v.to_vec() .try_into() .map_err(|_| DeError::invalid_length(v.len(), &self))?, )) } fn visit_str(self, v: &str) -> Result where E: DeError, { Ok(Cow::Owned( v.as_bytes() .to_vec() .try_into() .map_err(|_| DeError::invalid_length(v.len(), &self))?, )) } fn visit_byte_buf(self, v: Vec) -> Result where E: DeError, { let len = v.len(); Ok(Cow::Owned( v.try_into() .map_err(|_| DeError::invalid_length(len, &self))?, )) } fn visit_string(self, v: String) -> Result where E: DeError, { let len = v.len(); Ok(Cow::Owned( v.into_bytes() .try_into() .map_err(|_| DeError::invalid_length(len, &self))?, )) } fn visit_seq(self, seq: V) -> Result where V: SeqAccess<'de>, { Ok(Cow::Owned(utils::array_from_iterator( utils::SeqIter::new(seq), &self, )?)) } } deserializer.deserialize_bytes(CowVisitor) } } #[cfg(feature = "alloc")] impl<'de, const N: usize> DeserializeAs<'de, Box<[u8; N]>> for Bytes { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Bytes::deserialize_as(deserializer).map(Box::new) } } #[cfg(feature = "alloc")] impl<'de, T, TAs, FORMAT> DeserializeAs<'de, Vec> for OneOrMany where TAs: DeserializeAs<'de, T>, FORMAT: Format, { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let is_hr = deserializer.is_human_readable(); let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?; let one_err: D::Error = match >::deserialize( content::de::ContentRefDeserializer::new(&content, is_hr), ) { Ok(one) => return Ok(alloc::vec![one.into_inner()]), Err(err) => err, }; let many_err: D::Error = match , Vec>>::deserialize( content::de::ContentDeserializer::new(content, is_hr), ) { Ok(many) => return Ok(many.into_inner()), Err(err) => err, }; Err(DeError::custom(format_args!( "OneOrMany could not deserialize any variant:\n One: {}\n Many: {}", one_err, many_err ))) } } #[cfg(feature = "alloc")] impl<'de, T, TAs1> DeserializeAs<'de, T> for PickFirst<(TAs1,)> where TAs1: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { Ok(DeserializeAsWrap::::deserialize(deserializer)?.into_inner()) } } #[cfg(feature = "alloc")] impl<'de, T, TAs1, TAs2> DeserializeAs<'de, T> for PickFirst<(TAs1, TAs2)> where TAs1: DeserializeAs<'de, T>, TAs2: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { let is_hr = deserializer.is_human_readable(); let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?; let first_err: D::Error = match >::deserialize( content::de::ContentRefDeserializer::new(&content, is_hr), ) { Ok(first) => return Ok(first.into_inner()), Err(err) => err, }; let second_err: D::Error = match >::deserialize( content::de::ContentDeserializer::new(content, is_hr), ) { Ok(second) => return Ok(second.into_inner()), Err(err) => err, }; Err(DeError::custom(format_args!( "PickFirst could not deserialize any variant:\n First: {}\n Second: {}", first_err, second_err ))) } } #[cfg(feature = "alloc")] impl<'de, T, TAs1, TAs2, TAs3> DeserializeAs<'de, T> for PickFirst<(TAs1, TAs2, TAs3)> where TAs1: DeserializeAs<'de, T>, TAs2: DeserializeAs<'de, T>, TAs3: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { let is_hr = deserializer.is_human_readable(); let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?; let first_err: D::Error = match >::deserialize( content::de::ContentRefDeserializer::new(&content, is_hr), ) { Ok(first) => return Ok(first.into_inner()), Err(err) => err, }; let second_err: D::Error = match >::deserialize( content::de::ContentRefDeserializer::new(&content, is_hr), ) { Ok(second) => return Ok(second.into_inner()), Err(err) => err, }; let third_err: D::Error = match >::deserialize( content::de::ContentDeserializer::new(content, is_hr), ) { Ok(third) => return Ok(third.into_inner()), Err(err) => err, }; Err(DeError::custom(format_args!( "PickFirst could not deserialize any variant:\n First: {}\n Second: {}\n Third: {}", first_err, second_err, third_err, ))) } } #[cfg(feature = "alloc")] impl<'de, T, TAs1, TAs2, TAs3, TAs4> DeserializeAs<'de, T> for PickFirst<(TAs1, TAs2, TAs3, TAs4)> where TAs1: DeserializeAs<'de, T>, TAs2: DeserializeAs<'de, T>, TAs3: DeserializeAs<'de, T>, TAs4: DeserializeAs<'de, T>, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { let is_hr = deserializer.is_human_readable(); let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?; let first_err: D::Error = match >::deserialize( content::de::ContentRefDeserializer::new(&content, is_hr), ) { Ok(first) => return Ok(first.into_inner()), Err(err) => err, }; let second_err: D::Error = match >::deserialize( content::de::ContentRefDeserializer::new(&content, is_hr), ) { Ok(second) => return Ok(second.into_inner()), Err(err) => err, }; let third_err: D::Error = match >::deserialize( content::de::ContentRefDeserializer::new(&content, is_hr), ) { Ok(third) => return Ok(third.into_inner()), Err(err) => err, }; let fourth_err: D::Error = match >::deserialize( content::de::ContentDeserializer::new(content, is_hr), ) { Ok(fourth) => return Ok(fourth.into_inner()), Err(err) => err, }; Err(DeError::custom(format_args!( "PickFirst could not deserialize any variant:\n First: {}\n Second: {}\n Third: {}\n Fourth: {}", first_err, second_err, third_err, fourth_err, ))) } } impl<'de, T, U> DeserializeAs<'de, T> for FromInto where U: Into, U: Deserialize<'de>, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { Ok(U::deserialize(deserializer)?.into()) } } impl<'de, T, U> DeserializeAs<'de, T> for TryFromInto where U: TryInto, >::Error: Display, U: Deserialize<'de>, { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { U::deserialize(deserializer)? .try_into() .map_err(DeError::custom) } } #[cfg(feature = "alloc")] impl<'de> DeserializeAs<'de, Cow<'de, str>> for BorrowCow { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { struct CowVisitor; impl<'de> Visitor<'de> for CowVisitor { type Value = Cow<'de, str>; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("an optionally borrowed string") } fn visit_borrowed_str(self, v: &'de str) -> Result where E: DeError, { Ok(Cow::Borrowed(v)) } fn visit_str(self, v: &str) -> Result where E: DeError, { Ok(Cow::Owned(v.to_owned())) } fn visit_string(self, v: String) -> Result where E: DeError, { Ok(Cow::Owned(v)) } } deserializer.deserialize_string(CowVisitor) } } #[cfg(feature = "alloc")] impl<'de> DeserializeAs<'de, Cow<'de, [u8]>> for BorrowCow { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Bytes::deserialize_as(deserializer) } } #[cfg(feature = "alloc")] impl<'de, const N: usize> DeserializeAs<'de, Cow<'de, [u8; N]>> for BorrowCow { fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { Bytes::deserialize_as(deserializer) } } impl<'de> DeserializeAs<'de, bool> for BoolFromInt { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { struct U8Visitor; impl<'de> Visitor<'de> for U8Visitor { type Value = bool; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("an integer 0 or 1") } fn visit_u8(self, v: u8) -> Result where E: DeError, { match v { 0 => Ok(false), 1 => Ok(true), unexp => Err(DeError::invalid_value( Unexpected::Unsigned(unexp as u64), &"0 or 1", )), } } fn visit_i8(self, v: i8) -> Result where E: DeError, { match v { 0 => Ok(false), 1 => Ok(true), unexp => Err(DeError::invalid_value( Unexpected::Signed(unexp as i64), &"0 or 1", )), } } fn visit_u64(self, v: u64) -> Result where E: DeError, { match v { 0 => Ok(false), 1 => Ok(true), unexp => Err(DeError::invalid_value( Unexpected::Unsigned(unexp), &"0 or 1", )), } } fn visit_i64(self, v: i64) -> Result where E: DeError, { match v { 0 => Ok(false), 1 => Ok(true), unexp => Err(DeError::invalid_value(Unexpected::Signed(unexp), &"0 or 1")), } } fn visit_u128(self, v: u128) -> Result where E: DeError, { match v { 0 => Ok(false), 1 => Ok(true), unexp => Err(DeError::invalid_value( Unexpected::Unsigned(unexp as u64), &"0 or 1", )), } } fn visit_i128(self, v: i128) -> Result where E: DeError, { match v { 0 => Ok(false), 1 => Ok(true), unexp => Err(DeError::invalid_value( Unexpected::Signed(unexp as i64), &"0 or 1", )), } } } deserializer.deserialize_u8(U8Visitor) } } impl<'de> DeserializeAs<'de, bool> for BoolFromInt { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { struct U8Visitor; impl<'de> Visitor<'de> for U8Visitor { type Value = bool; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("an integer") } fn visit_u8(self, v: u8) -> Result where E: DeError, { Ok(v != 0) } fn visit_i8(self, v: i8) -> Result where E: DeError, { Ok(v != 0) } fn visit_u64(self, v: u64) -> Result where E: DeError, { Ok(v != 0) } fn visit_i64(self, v: i64) -> Result where E: DeError, { Ok(v != 0) } fn visit_u128(self, v: u128) -> Result where E: DeError, { Ok(v != 0) } fn visit_i128(self, v: i128) -> Result where E: DeError, { Ok(v != 0) } } deserializer.deserialize_u8(U8Visitor) } } // endregion