pub(crate) use self::macros::*; use crate::{formats::Strictness, prelude::*}; #[cfg(feature = "hashbrown_0_14")] use hashbrown_0_14::{HashMap as HashbrownMap014, HashSet as HashbrownSet014}; #[cfg(feature = "hashbrown_0_15")] use hashbrown_0_15::{HashMap as HashbrownMap015, HashSet as HashbrownSet015}; #[cfg(feature = "indexmap_1")] use indexmap_1::{IndexMap, IndexSet}; #[cfg(feature = "indexmap_2")] use indexmap_2::{IndexMap as IndexMap2, IndexSet as IndexSet2}; /////////////////////////////////////////////////////////////////////////////// // Helper macro used internally #[cfg(feature = "alloc")] type BoxedSlice = Box<[T]>; type Slice = [T]; type Ref<'a, T> = &'a T; type RefMut<'a, T> = &'a mut T; pub(crate) mod macros { // The unused_imports lint has false-positives around macros // https://github.com/rust-lang/rust/issues/78894 #![allow(unused_imports)] macro_rules! foreach_map { ($m:ident) => { #[cfg(feature = "alloc")] $m!(BTreeMap); #[cfg(feature = "std")] $m!(HashMap); #[cfg(feature = "hashbrown_0_14")] $m!(HashbrownMap014); #[cfg(feature = "hashbrown_0_15")] $m!(HashbrownMap015); #[cfg(feature = "indexmap_1")] $m!(IndexMap); #[cfg(feature = "indexmap_2")] $m!(IndexMap2); }; } macro_rules! foreach_set { ($m:ident, $T:tt) => { #[cfg(feature = "alloc")] $m!(BTreeSet<$T>); #[cfg(feature = "std")] $m!(HashSet<$T, H: Sized>); #[cfg(feature = "hashbrown_0_14")] $m!(HashbrownSet014<$T, H: Sized>); #[cfg(feature = "hashbrown_0_15")] $m!(HashbrownSet015<$T, H: Sized>); #[cfg(feature = "indexmap_1")] $m!(IndexSet<$T, H: Sized>); #[cfg(feature = "indexmap_2")] $m!(IndexSet2<$T, H: Sized>); }; ($m:ident) => { foreach_set!($m, T); }; } macro_rules! foreach_seq { ($m:ident, $T:tt) => { foreach_set!($m, $T); $m!(Slice<$T>); #[cfg(feature = "alloc")] $m!(BinaryHeap<$T>); #[cfg(feature = "alloc")] $m!(BoxedSlice<$T>); #[cfg(feature = "alloc")] $m!(LinkedList<$T>); #[cfg(feature = "alloc")] $m!(Vec<$T>); #[cfg(feature = "alloc")] $m!(VecDeque<$T>); }; ($m: ident) => { foreach_seq!($m, T); }; } // Make the macros available to the rest of the crate pub(crate) use foreach_map; pub(crate) use foreach_seq; pub(crate) use foreach_set; } /////////////////////////////////////////////////////////////////////////////// // region: Simple Wrapper types (e.g., Box, Option) #[allow(unused_macros)] macro_rules! pinned_wrapper { ($wrapper:ident $($lifetime:lifetime)?) => { impl<$($lifetime,)? T, U> SerializeAs>> for Pin<$wrapper<$($lifetime,)? U>> where U: SerializeAs, { fn serialize_as(source: &Pin<$wrapper<$($lifetime,)? T>>, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } }; } impl<'a, T, U> SerializeAs<&'a T> for &'a U where U: SerializeAs, T: ?Sized, U: ?Sized, { fn serialize_as(source: &&'a T, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } impl<'a, T, U> SerializeAs<&'a mut T> for &'a mut U where U: SerializeAs, T: ?Sized, U: ?Sized, { fn serialize_as(source: &&'a mut T, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } pinned_wrapper!(Ref 'a); pinned_wrapper!(RefMut 'a); #[cfg(feature = "alloc")] impl SerializeAs> for Box where U: SerializeAs, { fn serialize_as(source: &Box, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } #[cfg(feature = "alloc")] pinned_wrapper!(Box); impl SerializeAs> for Option where U: SerializeAs, { fn serialize_as(source: &Option, serializer: S) -> Result where S: Serializer, { match *source { Some(ref value) => serializer.serialize_some(&SerializeAsWrap::::new(value)), None => serializer.serialize_none(), } } } impl SerializeAs> for Bound where U: SerializeAs, T: Sized, { fn serialize_as(source: &Bound, serializer: S) -> Result where S: Serializer, { match source { Bound::Unbounded => Bound::Unbounded, Bound::Included(ref v) => Bound::Included(SerializeAsWrap::::new(v)), Bound::Excluded(ref v) => Bound::Excluded(SerializeAsWrap::::new(v)), } .serialize(serializer) } } #[cfg(feature = "alloc")] impl SerializeAs> for Rc where U: SerializeAs, { fn serialize_as(source: &Rc, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } #[cfg(feature = "alloc")] pinned_wrapper!(Rc); #[cfg(feature = "alloc")] impl SerializeAs> for RcWeak where U: SerializeAs, { fn serialize_as(source: &RcWeak, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::>, Option>>::new(&source.upgrade()) .serialize(serializer) } } #[cfg(all(feature = "alloc", target_has_atomic = "ptr"))] impl SerializeAs> for Arc where U: SerializeAs, { fn serialize_as(source: &Arc, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } #[cfg(all(feature = "alloc", target_has_atomic = "ptr"))] pinned_wrapper!(Arc); #[cfg(all(feature = "alloc", target_has_atomic = "ptr"))] impl SerializeAs> for ArcWeak where U: SerializeAs, { fn serialize_as(source: &ArcWeak, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::>, Option>>::new(&source.upgrade()) .serialize(serializer) } } impl SerializeAs> for Cell where U: SerializeAs, T: Copy, { fn serialize_as(source: &Cell, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(&source.get()).serialize(serializer) } } impl SerializeAs> for RefCell where U: SerializeAs, { fn serialize_as(source: &RefCell, serializer: S) -> Result where S: Serializer, { match source.try_borrow() { Ok(source) => SerializeAsWrap::::new(&*source).serialize(serializer), Err(_) => Err(S::Error::custom("already mutably borrowed")), } } } #[cfg(feature = "std")] impl SerializeAs> for Mutex where U: SerializeAs, { fn serialize_as(source: &Mutex, serializer: S) -> Result where S: Serializer, { match source.lock() { Ok(source) => SerializeAsWrap::::new(&*source).serialize(serializer), Err(_) => Err(S::Error::custom("lock poison error while serializing")), } } } #[cfg(feature = "std")] impl SerializeAs> for RwLock where U: SerializeAs, { fn serialize_as(source: &RwLock, serializer: S) -> Result where S: Serializer, { match source.read() { Ok(source) => SerializeAsWrap::::new(&*source).serialize(serializer), Err(_) => Err(S::Error::custom("lock poison error while serializing")), } } } impl SerializeAs> for Result where TAs: SerializeAs, EAs: SerializeAs, { fn serialize_as(source: &Result, serializer: S) -> Result where S: Serializer, { source .as_ref() .map(SerializeAsWrap::::new) .map_err(SerializeAsWrap::::new) .serialize(serializer) } } impl SerializeAs<[T; N]> for [As; N] where As: SerializeAs, { fn serialize_as(array: &[T; N], serializer: S) -> Result where S: Serializer, { let mut arr = serializer.serialize_tuple(N)?; for elem in array { arr.serialize_element(&SerializeAsWrap::::new(elem))?; } arr.end() } } // endregion /////////////////////////////////////////////////////////////////////////////// // region: Collection Types (e.g., Maps, Sets, Vec) macro_rules! seq_impl { ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident )* >) => { impl SerializeAs<$ty> for $ty where U: SerializeAs, $(T: ?Sized + $tbound1 $(+ $tbound2)*,)* $($typaram: ?Sized + $bound,)* { fn serialize_as(source: &$ty, serializer: S) -> Result where S: Serializer, { serializer.collect_seq(source.iter().map(|item| SerializeAsWrap::::new(item))) } } } } foreach_seq!(seq_impl); #[cfg(feature = "alloc")] macro_rules! map_impl { ($ty:ident < K, V $(, $typaram:ident : $bound:ident)* >) => { impl SerializeAs<$ty> for $ty where KU: SerializeAs, VU: SerializeAs, $($typaram: ?Sized + $bound,)* { fn serialize_as(source: &$ty, serializer: S) -> Result where S: Serializer, { serializer.collect_map(source.iter().map(|(k, v)| (SerializeAsWrap::::new(k), SerializeAsWrap::::new(v)))) } } } } foreach_map!(map_impl); macro_rules! tuple_impl { ($len:literal $($n:tt $t:ident $tas:ident)+) => { impl<$($t, $tas,)+> SerializeAs<($($t,)+)> for ($($tas,)+) where $($tas: SerializeAs<$t>,)+ { fn serialize_as(tuple: &($($t,)+), serializer: S) -> Result where S: Serializer, { use serde::ser::SerializeTuple; let mut tup = serializer.serialize_tuple($len)?; $( tup.serialize_element(&SerializeAsWrap::<$t, $tas>::new(&tuple.$n))?; )+ tup.end() } } }; } 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, V $(, $typaram:ident : $bound:ident)* >, $ty:ident <(K, V)>) => { impl SerializeAs<$tyorig> for $ty<(KAs, VAs)> where KAs: SerializeAs, VAs: SerializeAs, $($typaram: ?Sized + $bound,)* { fn serialize_as(source: &$tyorig, serializer: S) -> Result where S: Serializer, { serializer.collect_seq(source.iter().map(|(k, v)| { ( SerializeAsWrap::::new(k), SerializeAsWrap::::new(v), ) })) } } }; } #[cfg(feature = "alloc")] macro_rules! map_as_tuple_seq { ($tyorig:ident < K, V $(, $typaram:ident : $bound:ident)* >) => { map_as_tuple_seq_intern!($tyorig, Seq<(K, V)>); #[cfg(feature = "alloc")] map_as_tuple_seq_intern!($tyorig, Vec<(K, V)>); } } foreach_map!(map_as_tuple_seq); macro_rules! tuple_seq_as_map_impl_intern { ($tyorig:ident < (K, V) $(, $typaram:ident : $bound:ident)* >, $ty:ident ) => { #[allow(clippy::implicit_hasher)] impl SerializeAs<$tyorig<(K, V) $(, $typaram)*>> for $ty where KAs: SerializeAs, VAs: SerializeAs, $($typaram: ?Sized + $bound,)* { fn serialize_as(source: &$tyorig<(K, V) $(, $typaram)*>, serializer: S) -> Result where S: Serializer, { serializer.collect_map(source.iter().map(|(k, v)| { ( SerializeAsWrap::::new(k), SerializeAsWrap::::new(v), ) })) } } }; } macro_rules! tuple_seq_as_map_impl { ($tyorig:ident < (K, V) $(, $typaram:ident : $bound:ident)* >) => { tuple_seq_as_map_impl_intern!($tyorig<(K, V) $(, $typaram: $bound)* >, Map); #[cfg(feature = "alloc")] tuple_seq_as_map_impl_intern!($tyorig<(K, V) $(, $typaram: $bound)* >, BTreeMap); #[cfg(feature = "std")] tuple_seq_as_map_impl_intern!($tyorig<(K, V) $(, $typaram: $bound)* >, HashMap); } } foreach_seq!(tuple_seq_as_map_impl, (K, V)); tuple_seq_as_map_impl!(Option<(K, V)>); macro_rules! tuple_seq_as_map_arr { ($tyorig:ty, $ty:ident ) => { #[allow(clippy::implicit_hasher)] impl SerializeAs<$tyorig> for $ty where KAs: SerializeAs, VAs: SerializeAs, { fn serialize_as(source: &$tyorig, serializer: S) -> Result where S: Serializer, { serializer.collect_map(source.iter().map(|(k, v)| { ( SerializeAsWrap::::new(k), SerializeAsWrap::::new(v), ) })) } } }; } tuple_seq_as_map_arr!([(K, V); N], Map); #[cfg(feature = "alloc")] tuple_seq_as_map_arr!([(K, V); N], BTreeMap); #[cfg(feature = "std")] tuple_seq_as_map_arr!([(K, V); N], HashMap); // endregion /////////////////////////////////////////////////////////////////////////////// // region: Conversion types which cause different serialization behavior impl SerializeAs for Same where T: Serialize + ?Sized, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { source.serialize(serializer) } } impl SerializeAs for DisplayFromStr where T: Display, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { serializer.collect_str(source) } } impl SerializeAs for IfIsHumanReadable where T: ?Sized, H: SerializeAs, F: SerializeAs, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { if serializer.is_human_readable() { H::serialize_as(source, serializer) } else { F::serialize_as(source, serializer) } } } impl SerializeAs> for NoneAsEmptyString where T: Display, { fn serialize_as(source: &Option, serializer: S) -> Result where S: Serializer, { if let Some(value) = source { serializer.collect_str(value) } else { serializer.serialize_str("") } } } #[cfg(feature = "alloc")] impl SerializeAs for DefaultOnError where TAs: SerializeAs, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { TAs::serialize_as(source, serializer) } } #[cfg(feature = "alloc")] impl SerializeAs> for BytesOrString { fn serialize_as(source: &Vec, serializer: S) -> Result where S: Serializer, { source.serialize(serializer) } } impl SerializeAs for StringWithSeparator where SEPARATOR: formats::Separator, for<'x> &'x I: IntoIterator, T: Display, // This set of bounds is enough to make the function compile but has inference issues // making it unusable at the moment. // https://github.com/rust-lang/rust/issues/89196#issuecomment-932024770 // for<'x> &'x I: IntoIterator, // for<'x> <&'x I as IntoIterator>::Item: Display, { fn serialize_as(source: &I, serializer: S) -> Result where S: Serializer, { pub(crate) struct DisplayWithSeparator<'a, I, SEPARATOR>(&'a I, PhantomData); impl<'a, I, SEPARATOR> DisplayWithSeparator<'a, I, SEPARATOR> { pub(crate) fn new(iter: &'a I) -> Self { Self(iter, PhantomData) } } impl<'a, I, SEPARATOR> Display for DisplayWithSeparator<'a, I, SEPARATOR> where SEPARATOR: formats::Separator, &'a I: IntoIterator, <&'a I as IntoIterator>::Item: Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut iter = self.0.into_iter(); if let Some(first) = iter.next() { first.fmt(f)?; } for elem in iter { f.write_str(SEPARATOR::separator())?; elem.fmt(f)?; } Ok(()) } } serializer.collect_str(&DisplayWithSeparator::::new(source)) } } macro_rules! use_signed_duration { ( $main_trait:ident $internal_trait:ident => { $ty:ty => $({ $format:ty, $strictness:ty => $($tbound:ident: $bound:ident $(,)?)* })* } ) => { $( impl<$($tbound,)*> SerializeAs<$ty> for $main_trait<$format, $strictness> where $($tbound: $bound,)* { fn serialize_as(source: &$ty, serializer: S) -> Result where S: Serializer, { $internal_trait::<$format, $strictness>::serialize_as( &DurationSigned::from(source), serializer, ) } } )* }; ( $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt ) => { $( use_signed_duration!($main_trait $internal_trait => $rest); )+ }; } use_signed_duration!( DurationSeconds DurationSeconds, DurationMilliSeconds DurationMilliSeconds, DurationMicroSeconds DurationMicroSeconds, DurationNanoSeconds DurationNanoSeconds, => { Duration => {u64, STRICTNESS => STRICTNESS: Strictness} {f64, STRICTNESS => STRICTNESS: Strictness} } ); #[cfg(feature = "alloc")] use_signed_duration!( DurationSeconds DurationSeconds, DurationMilliSeconds DurationMilliSeconds, DurationMicroSeconds DurationMicroSeconds, DurationNanoSeconds DurationNanoSeconds, => { Duration => {String, STRICTNESS => STRICTNESS: Strictness} } ); use_signed_duration!( DurationSecondsWithFrac DurationSecondsWithFrac, DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac, DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac, DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac, => { Duration => {f64, STRICTNESS => STRICTNESS: Strictness} } ); #[cfg(feature = "alloc")] use_signed_duration!( DurationSecondsWithFrac DurationSecondsWithFrac, DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac, DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac, DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac, => { Duration => {String, STRICTNESS => STRICTNESS: Strictness} } ); #[cfg(feature = "std")] use_signed_duration!( TimestampSeconds DurationSeconds, TimestampMilliSeconds DurationMilliSeconds, TimestampMicroSeconds DurationMicroSeconds, TimestampNanoSeconds DurationNanoSeconds, => { SystemTime => {i64, STRICTNESS => STRICTNESS: Strictness} {f64, STRICTNESS => STRICTNESS: Strictness} {String, STRICTNESS => STRICTNESS: Strictness} } ); #[cfg(feature = "std")] use_signed_duration!( TimestampSecondsWithFrac DurationSecondsWithFrac, TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac, TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac, TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac, => { SystemTime => {f64, STRICTNESS => STRICTNESS: Strictness} {String, STRICTNESS => STRICTNESS: Strictness} } ); impl SerializeAs for DefaultOnNull where U: SerializeAs, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { serializer.serialize_some(&SerializeAsWrap::::new(source)) } } impl SerializeAs<&[u8]> for Bytes { fn serialize_as(bytes: &&[u8], serializer: S) -> Result where S: Serializer, { serializer.serialize_bytes(bytes) } } #[cfg(feature = "alloc")] impl SerializeAs> for Bytes { fn serialize_as(bytes: &Vec, serializer: S) -> Result where S: Serializer, { serializer.serialize_bytes(bytes) } } #[cfg(feature = "alloc")] impl SerializeAs> for Bytes { fn serialize_as(bytes: &Box<[u8]>, serializer: S) -> Result where S: Serializer, { serializer.serialize_bytes(bytes) } } #[cfg(feature = "alloc")] impl<'a> SerializeAs> for Bytes { fn serialize_as(bytes: &Cow<'a, [u8]>, serializer: S) -> Result where S: Serializer, { serializer.serialize_bytes(bytes) } } impl SerializeAs<[u8; N]> for Bytes { fn serialize_as(bytes: &[u8; N], serializer: S) -> Result where S: Serializer, { serializer.serialize_bytes(bytes) } } impl SerializeAs<&[u8; N]> for Bytes { fn serialize_as(bytes: &&[u8; N], serializer: S) -> Result where S: Serializer, { serializer.serialize_bytes(*bytes) } } #[cfg(feature = "alloc")] impl SerializeAs> for Bytes { fn serialize_as(bytes: &Box<[u8; N]>, serializer: S) -> Result where S: Serializer, { serializer.serialize_bytes(&**bytes) } } #[cfg(feature = "alloc")] impl<'a, const N: usize> SerializeAs> for Bytes { fn serialize_as(bytes: &Cow<'a, [u8; N]>, serializer: S) -> Result where S: Serializer, { serializer.serialize_bytes(bytes.as_ref()) } } #[cfg(feature = "alloc")] impl SerializeAs> for OneOrMany where U: SerializeAs, { fn serialize_as(source: &Vec, serializer: S) -> Result where S: Serializer, { match source.len() { 1 => SerializeAsWrap::::new(source.iter().next().expect("Cannot be empty")) .serialize(serializer), _ => SerializeAsWrap::, Vec>::new(source).serialize(serializer), } } } #[cfg(feature = "alloc")] impl SerializeAs> for OneOrMany where U: SerializeAs, { fn serialize_as(source: &Vec, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::, Vec>::new(source).serialize(serializer) } } #[cfg(feature = "alloc")] impl SerializeAs for PickFirst<(TAs1,)> where TAs1: SerializeAs, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } #[cfg(feature = "alloc")] impl SerializeAs for PickFirst<(TAs1, TAs2)> where TAs1: SerializeAs, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } #[cfg(feature = "alloc")] impl SerializeAs for PickFirst<(TAs1, TAs2, TAs3)> where TAs1: SerializeAs, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } #[cfg(feature = "alloc")] impl SerializeAs for PickFirst<(TAs1, TAs2, TAs3, TAs4)> where TAs1: SerializeAs, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { SerializeAsWrap::::new(source).serialize(serializer) } } impl SerializeAs for FromInto where T: Into + Clone, U: Serialize, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { source.clone().into().serialize(serializer) } } impl SerializeAs for TryFromInto where T: TryInto + Clone, >::Error: Display, U: Serialize, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { source .clone() .try_into() .map_err(S::Error::custom)? .serialize(serializer) } } impl SerializeAs for FromIntoRef where for<'a> &'a T: Into, U: Serialize, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { source.into().serialize(serializer) } } impl SerializeAs for TryFromIntoRef where for<'a> &'a T: TryInto, for<'a> <&'a T as TryInto>::Error: Display, U: Serialize, { fn serialize_as(source: &T, serializer: S) -> Result where S: Serializer, { source .try_into() .map_err(S::Error::custom)? .serialize(serializer) } } #[cfg(feature = "alloc")] impl<'a> SerializeAs> for BorrowCow { fn serialize_as(source: &Cow<'a, str>, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(source) } } #[cfg(feature = "alloc")] impl<'a> SerializeAs> for BorrowCow { fn serialize_as(value: &Cow<'a, [u8]>, serializer: S) -> Result where S: Serializer, { serializer.collect_seq(value.iter()) } } #[cfg(feature = "alloc")] impl<'a, const N: usize> SerializeAs> for BorrowCow { fn serialize_as(value: &Cow<'a, [u8; N]>, serializer: S) -> Result where S: Serializer, { serializer.collect_seq(value.iter()) } } impl SerializeAs for BoolFromInt { fn serialize_as(source: &bool, serializer: S) -> Result where S: Serializer, { serializer.serialize_u8(u8::from(*source)) } } // endregion