serde_with/ser/
impls.rs

1pub(crate) use self::macros::*;
2use crate::{formats::Strictness, prelude::*};
3#[cfg(feature = "hashbrown_0_14")]
4use hashbrown_0_14::{HashMap as HashbrownMap014, HashSet as HashbrownSet014};
5#[cfg(feature = "hashbrown_0_15")]
6use hashbrown_0_15::{HashMap as HashbrownMap015, HashSet as HashbrownSet015};
7#[cfg(feature = "indexmap_1")]
8use indexmap_1::{IndexMap, IndexSet};
9#[cfg(feature = "indexmap_2")]
10use indexmap_2::{IndexMap as IndexMap2, IndexSet as IndexSet2};
11
12///////////////////////////////////////////////////////////////////////////////
13// Helper macro used internally
14
15#[cfg(feature = "alloc")]
16type BoxedSlice<T> = Box<[T]>;
17type Slice<T> = [T];
18type Ref<'a, T> = &'a T;
19type RefMut<'a, T> = &'a mut T;
20
21pub(crate) mod macros {
22    // The unused_imports lint has false-positives around macros
23    // https://github.com/rust-lang/rust/issues/78894
24    #![allow(unused_imports)]
25
26    macro_rules! foreach_map {
27    ($m:ident) => {
28        #[cfg(feature = "alloc")]
29        $m!(BTreeMap<K, V>);
30        #[cfg(feature = "std")]
31        $m!(HashMap<K, V, H: Sized>);
32        #[cfg(feature = "hashbrown_0_14")]
33        $m!(HashbrownMap014<K, V, H: Sized>);
34        #[cfg(feature = "hashbrown_0_15")]
35        $m!(HashbrownMap015<K, V, H: Sized>);
36        #[cfg(feature = "indexmap_1")]
37        $m!(IndexMap<K, V, H: Sized>);
38        #[cfg(feature = "indexmap_2")]
39        $m!(IndexMap2<K, V, H: Sized>);
40    };
41}
42
43    macro_rules! foreach_set {
44    ($m:ident, $T:tt) => {
45        #[cfg(feature = "alloc")]
46        $m!(BTreeSet<$T>);
47        #[cfg(feature = "std")]
48        $m!(HashSet<$T, H: Sized>);
49        #[cfg(feature = "hashbrown_0_14")]
50        $m!(HashbrownSet014<$T, H: Sized>);
51        #[cfg(feature = "hashbrown_0_15")]
52        $m!(HashbrownSet015<$T, H: Sized>);
53        #[cfg(feature = "indexmap_1")]
54        $m!(IndexSet<$T, H: Sized>);
55        #[cfg(feature = "indexmap_2")]
56        $m!(IndexSet2<$T, H: Sized>);
57    };
58    ($m:ident) => {
59        foreach_set!($m, T);
60    };
61}
62
63    macro_rules! foreach_seq {
64        ($m:ident, $T:tt) => {
65            foreach_set!($m, $T);
66
67            $m!(Slice<$T>);
68
69            #[cfg(feature = "alloc")]
70            $m!(BinaryHeap<$T>);
71            #[cfg(feature = "alloc")]
72            $m!(BoxedSlice<$T>);
73            #[cfg(feature = "alloc")]
74            $m!(LinkedList<$T>);
75            #[cfg(feature = "alloc")]
76            $m!(Vec<$T>);
77            #[cfg(feature = "alloc")]
78            $m!(VecDeque<$T>);
79        };
80        ($m:
81            ident) => {
82            foreach_seq!($m, T);
83        };
84    }
85
86    // Make the macros available to the rest of the crate
87    pub(crate) use foreach_map;
88    pub(crate) use foreach_seq;
89    pub(crate) use foreach_set;
90}
91
92///////////////////////////////////////////////////////////////////////////////
93// region: Simple Wrapper types (e.g., Box, Option)
94
95#[allow(unused_macros)]
96macro_rules! pinned_wrapper {
97    ($wrapper:ident $($lifetime:lifetime)?) => {
98        impl<$($lifetime,)? T, U> SerializeAs<Pin<$wrapper<$($lifetime,)? T>>> for Pin<$wrapper<$($lifetime,)? U>>
99        where
100            U: SerializeAs<T>,
101        {
102            fn serialize_as<S>(source: &Pin<$wrapper<$($lifetime,)? T>>, serializer: S) -> Result<S::Ok, S::Error>
103            where
104                S: Serializer,
105            {
106                SerializeAsWrap::<T, U>::new(source).serialize(serializer)
107            }
108        }
109    };
110}
111
112impl<'a, T, U> SerializeAs<&'a T> for &'a U
113where
114    U: SerializeAs<T>,
115    T: ?Sized,
116    U: ?Sized,
117{
118    fn serialize_as<S>(source: &&'a T, serializer: S) -> Result<S::Ok, S::Error>
119    where
120        S: Serializer,
121    {
122        SerializeAsWrap::<T, U>::new(source).serialize(serializer)
123    }
124}
125
126impl<'a, T, U> SerializeAs<&'a mut T> for &'a mut U
127where
128    U: SerializeAs<T>,
129    T: ?Sized,
130    U: ?Sized,
131{
132    fn serialize_as<S>(source: &&'a mut T, serializer: S) -> Result<S::Ok, S::Error>
133    where
134        S: Serializer,
135    {
136        SerializeAsWrap::<T, U>::new(source).serialize(serializer)
137    }
138}
139
140pinned_wrapper!(Ref 'a);
141pinned_wrapper!(RefMut 'a);
142
143#[cfg(feature = "alloc")]
144impl<T, U> SerializeAs<Box<T>> for Box<U>
145where
146    U: SerializeAs<T>,
147{
148    fn serialize_as<S>(source: &Box<T>, serializer: S) -> Result<S::Ok, S::Error>
149    where
150        S: Serializer,
151    {
152        SerializeAsWrap::<T, U>::new(source).serialize(serializer)
153    }
154}
155
156#[cfg(feature = "alloc")]
157pinned_wrapper!(Box);
158
159impl<T, U> SerializeAs<Option<T>> for Option<U>
160where
161    U: SerializeAs<T>,
162{
163    fn serialize_as<S>(source: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
164    where
165        S: Serializer,
166    {
167        match *source {
168            Some(ref value) => serializer.serialize_some(&SerializeAsWrap::<T, U>::new(value)),
169            None => serializer.serialize_none(),
170        }
171    }
172}
173
174impl<T, U> SerializeAs<Bound<T>> for Bound<U>
175where
176    U: SerializeAs<T>,
177    T: Sized,
178{
179    fn serialize_as<S>(source: &Bound<T>, serializer: S) -> Result<S::Ok, S::Error>
180    where
181        S: Serializer,
182    {
183        match source {
184            Bound::Unbounded => Bound::Unbounded,
185            Bound::Included(v) => Bound::Included(SerializeAsWrap::<T, U>::new(v)),
186            Bound::Excluded(v) => Bound::Excluded(SerializeAsWrap::<T, U>::new(v)),
187        }
188        .serialize(serializer)
189    }
190}
191
192#[cfg(feature = "alloc")]
193impl<T, U> SerializeAs<Rc<T>> for Rc<U>
194where
195    U: SerializeAs<T>,
196{
197    fn serialize_as<S>(source: &Rc<T>, serializer: S) -> Result<S::Ok, S::Error>
198    where
199        S: Serializer,
200    {
201        SerializeAsWrap::<T, U>::new(source).serialize(serializer)
202    }
203}
204
205#[cfg(feature = "alloc")]
206pinned_wrapper!(Rc);
207
208#[cfg(feature = "alloc")]
209impl<T, U> SerializeAs<RcWeak<T>> for RcWeak<U>
210where
211    U: SerializeAs<T>,
212{
213    fn serialize_as<S>(source: &RcWeak<T>, serializer: S) -> Result<S::Ok, S::Error>
214    where
215        S: Serializer,
216    {
217        SerializeAsWrap::<Option<Rc<T>>, Option<Rc<U>>>::new(&source.upgrade())
218            .serialize(serializer)
219    }
220}
221
222#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))]
223impl<T, U> SerializeAs<Arc<T>> for Arc<U>
224where
225    U: SerializeAs<T>,
226{
227    fn serialize_as<S>(source: &Arc<T>, serializer: S) -> Result<S::Ok, S::Error>
228    where
229        S: Serializer,
230    {
231        SerializeAsWrap::<T, U>::new(source).serialize(serializer)
232    }
233}
234
235#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))]
236pinned_wrapper!(Arc);
237
238#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))]
239impl<T, U> SerializeAs<ArcWeak<T>> for ArcWeak<U>
240where
241    U: SerializeAs<T>,
242{
243    fn serialize_as<S>(source: &ArcWeak<T>, serializer: S) -> Result<S::Ok, S::Error>
244    where
245        S: Serializer,
246    {
247        SerializeAsWrap::<Option<Arc<T>>, Option<Arc<U>>>::new(&source.upgrade())
248            .serialize(serializer)
249    }
250}
251
252impl<T, U> SerializeAs<Cell<T>> for Cell<U>
253where
254    U: SerializeAs<T>,
255    T: Copy,
256{
257    fn serialize_as<S>(source: &Cell<T>, serializer: S) -> Result<S::Ok, S::Error>
258    where
259        S: Serializer,
260    {
261        SerializeAsWrap::<T, U>::new(&source.get()).serialize(serializer)
262    }
263}
264
265impl<T, U> SerializeAs<RefCell<T>> for RefCell<U>
266where
267    U: SerializeAs<T>,
268{
269    fn serialize_as<S>(source: &RefCell<T>, serializer: S) -> Result<S::Ok, S::Error>
270    where
271        S: Serializer,
272    {
273        match source.try_borrow() {
274            Ok(source) => SerializeAsWrap::<T, U>::new(&*source).serialize(serializer),
275            Err(_) => Err(S::Error::custom("already mutably borrowed")),
276        }
277    }
278}
279
280#[cfg(feature = "std")]
281impl<T, U> SerializeAs<Mutex<T>> for Mutex<U>
282where
283    U: SerializeAs<T>,
284{
285    fn serialize_as<S>(source: &Mutex<T>, serializer: S) -> Result<S::Ok, S::Error>
286    where
287        S: Serializer,
288    {
289        match source.lock() {
290            Ok(source) => SerializeAsWrap::<T, U>::new(&*source).serialize(serializer),
291            Err(_) => Err(S::Error::custom("lock poison error while serializing")),
292        }
293    }
294}
295
296#[cfg(feature = "std")]
297impl<T, U> SerializeAs<RwLock<T>> for RwLock<U>
298where
299    U: SerializeAs<T>,
300{
301    fn serialize_as<S>(source: &RwLock<T>, serializer: S) -> Result<S::Ok, S::Error>
302    where
303        S: Serializer,
304    {
305        match source.read() {
306            Ok(source) => SerializeAsWrap::<T, U>::new(&*source).serialize(serializer),
307            Err(_) => Err(S::Error::custom("lock poison error while serializing")),
308        }
309    }
310}
311
312impl<T, TAs, E, EAs> SerializeAs<Result<T, E>> for Result<TAs, EAs>
313where
314    TAs: SerializeAs<T>,
315    EAs: SerializeAs<E>,
316{
317    fn serialize_as<S>(source: &Result<T, E>, serializer: S) -> Result<S::Ok, S::Error>
318    where
319        S: Serializer,
320    {
321        source
322            .as_ref()
323            .map(SerializeAsWrap::<T, TAs>::new)
324            .map_err(SerializeAsWrap::<E, EAs>::new)
325            .serialize(serializer)
326    }
327}
328
329impl<T, As, const N: usize> SerializeAs<[T; N]> for [As; N]
330where
331    As: SerializeAs<T>,
332{
333    fn serialize_as<S>(array: &[T; N], serializer: S) -> Result<S::Ok, S::Error>
334    where
335        S: Serializer,
336    {
337        let mut arr = serializer.serialize_tuple(N)?;
338        for elem in array {
339            arr.serialize_element(&SerializeAsWrap::<T, As>::new(elem))?;
340        }
341        arr.end()
342    }
343}
344
345// endregion
346///////////////////////////////////////////////////////////////////////////////
347// region: More complex wrappers that are not just a single value
348
349impl<Idx, IdxAs> SerializeAs<Range<Idx>> for Range<IdxAs>
350where
351    IdxAs: SerializeAs<Idx>,
352{
353    fn serialize_as<S>(value: &Range<Idx>, serializer: S) -> Result<S::Ok, S::Error>
354    where
355        S: Serializer,
356    {
357        Range {
358            start: SerializeAsWrap::<Idx, IdxAs>::new(&value.start),
359            end: SerializeAsWrap::<Idx, IdxAs>::new(&value.end),
360        }
361        .serialize(serializer)
362    }
363}
364
365impl<Idx, IdxAs> SerializeAs<RangeFrom<Idx>> for RangeFrom<IdxAs>
366where
367    IdxAs: SerializeAs<Idx>,
368{
369    fn serialize_as<S>(value: &RangeFrom<Idx>, serializer: S) -> Result<S::Ok, S::Error>
370    where
371        S: Serializer,
372    {
373        RangeFrom {
374            start: SerializeAsWrap::<Idx, IdxAs>::new(&value.start),
375        }
376        .serialize(serializer)
377    }
378}
379
380impl<Idx, IdxAs> SerializeAs<RangeInclusive<Idx>> for RangeInclusive<IdxAs>
381where
382    IdxAs: SerializeAs<Idx>,
383{
384    fn serialize_as<S>(value: &RangeInclusive<Idx>, serializer: S) -> Result<S::Ok, S::Error>
385    where
386        S: Serializer,
387    {
388        RangeInclusive::new(
389            SerializeAsWrap::<Idx, IdxAs>::new(value.start()),
390            SerializeAsWrap::<Idx, IdxAs>::new(value.end()),
391        )
392        .serialize(serializer)
393    }
394}
395
396impl<Idx, IdxAs> SerializeAs<RangeTo<Idx>> for RangeTo<IdxAs>
397where
398    IdxAs: SerializeAs<Idx>,
399{
400    fn serialize_as<S>(value: &RangeTo<Idx>, serializer: S) -> Result<S::Ok, S::Error>
401    where
402        S: Serializer,
403    {
404        RangeTo {
405            end: SerializeAsWrap::<Idx, IdxAs>::new(&value.end),
406        }
407        .serialize(serializer)
408    }
409}
410
411// endregion
412///////////////////////////////////////////////////////////////////////////////
413// region: Collection Types (e.g., Maps, Sets, Vec)
414
415macro_rules! seq_impl {
416    ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident )* >) => {
417        impl<T, U $(, $typaram)*> SerializeAs<$ty<T $(, $typaram)*>> for $ty<U $(, $typaram)*>
418        where
419            U: SerializeAs<T>,
420            $(T: ?Sized + $tbound1 $(+ $tbound2)*,)*
421            $($typaram: ?Sized + $bound,)*
422        {
423            fn serialize_as<S>(source: &$ty<T $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
424            where
425                S: Serializer,
426            {
427                serializer.collect_seq(source.iter().map(|item| SerializeAsWrap::<T, U>::new(item)))
428            }
429        }
430    }
431}
432foreach_seq!(seq_impl);
433
434#[cfg(feature = "alloc")]
435macro_rules! map_impl {
436    ($ty:ident < K, V $(, $typaram:ident : $bound:ident)* >) => {
437        impl<K, KU, V, VU $(, $typaram)*> SerializeAs<$ty<K, V $(, $typaram)*>> for $ty<KU, VU $(, $typaram)*>
438        where
439            KU: SerializeAs<K>,
440            VU: SerializeAs<V>,
441            $($typaram: ?Sized + $bound,)*
442        {
443            fn serialize_as<S>(source: &$ty<K, V $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
444            where
445                S: Serializer,
446            {
447                serializer.collect_map(source.iter().map(|(k, v)| (SerializeAsWrap::<K, KU>::new(k), SerializeAsWrap::<V, VU>::new(v))))
448            }
449        }
450    }
451}
452foreach_map!(map_impl);
453
454macro_rules! tuple_impl {
455    ($len:literal $($n:tt $t:ident $tas:ident)+) => {
456        impl<$($t, $tas,)+> SerializeAs<($($t,)+)> for ($($tas,)+)
457        where
458            $($tas: SerializeAs<$t>,)+
459        {
460            fn serialize_as<S>(tuple: &($($t,)+), serializer: S) -> Result<S::Ok, S::Error>
461            where
462                S: Serializer,
463            {
464                use serde::ser::SerializeTuple;
465                let mut tup = serializer.serialize_tuple($len)?;
466                $(
467                    tup.serialize_element(&SerializeAsWrap::<$t, $tas>::new(&tuple.$n))?;
468                )+
469                tup.end()
470            }
471        }
472    };
473}
474
475tuple_impl!(1 0 T0 As0);
476tuple_impl!(2 0 T0 As0 1 T1 As1);
477tuple_impl!(3 0 T0 As0 1 T1 As1 2 T2 As2);
478tuple_impl!(4 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3);
479tuple_impl!(5 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4);
480tuple_impl!(6 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5);
481tuple_impl!(7 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6);
482tuple_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);
483tuple_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);
484tuple_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);
485tuple_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);
486tuple_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);
487tuple_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);
488tuple_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);
489tuple_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);
490tuple_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);
491
492#[cfg(feature = "alloc")]
493macro_rules! map_as_tuple_seq_intern {
494    ($tyorig:ident < K, V $(, $typaram:ident : $bound:ident)* >, $ty:ident <(K, V)>) => {
495        impl<K, KAs, V, VAs $(, $typaram)*> SerializeAs<$tyorig<K, V $(, $typaram)*>> for $ty<(KAs, VAs)>
496        where
497            KAs: SerializeAs<K>,
498            VAs: SerializeAs<V>,
499            $($typaram: ?Sized + $bound,)*
500        {
501            fn serialize_as<S>(source: &$tyorig<K, V $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
502            where
503                S: Serializer,
504            {
505                serializer.collect_seq(source.iter().map(|(k, v)| {
506                    (
507                        SerializeAsWrap::<K, KAs>::new(k),
508                        SerializeAsWrap::<V, VAs>::new(v),
509                    )
510                }))
511            }
512        }
513    };
514}
515#[cfg(feature = "alloc")]
516macro_rules! map_as_tuple_seq {
517    ($tyorig:ident < K, V $(, $typaram:ident : $bound:ident)* >) => {
518        map_as_tuple_seq_intern!($tyorig<K, V $(, $typaram: $bound)* >, Seq<(K, V)>);
519        #[cfg(feature = "alloc")]
520        map_as_tuple_seq_intern!($tyorig<K, V $(, $typaram: $bound)* >, Vec<(K, V)>);
521    }
522}
523foreach_map!(map_as_tuple_seq);
524
525macro_rules! tuple_seq_as_map_impl_intern {
526    ($tyorig:ident < (K, V) $(, $typaram:ident : $bound:ident)* >, $ty:ident <K, V>) => {
527        #[allow(clippy::implicit_hasher)]
528        impl<K, KAs, V, VAs $(, $typaram)*> SerializeAs<$tyorig<(K, V) $(, $typaram)*>> for $ty<KAs, VAs>
529        where
530            KAs: SerializeAs<K>,
531            VAs: SerializeAs<V>,
532            $($typaram: ?Sized + $bound,)*
533        {
534            fn serialize_as<S>(source: &$tyorig<(K, V) $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
535            where
536                S: Serializer,
537            {
538                serializer.collect_map(source.iter().map(|(k, v)| {
539                    (
540                        SerializeAsWrap::<K, KAs>::new(k),
541                        SerializeAsWrap::<V, VAs>::new(v),
542                    )
543                }))
544            }
545        }
546    };
547}
548macro_rules! tuple_seq_as_map_impl {
549    ($tyorig:ident < (K, V) $(, $typaram:ident : $bound:ident)* >) => {
550        tuple_seq_as_map_impl_intern!($tyorig<(K, V) $(, $typaram: $bound)* >, Map<K, V>);
551        #[cfg(feature = "alloc")]
552        tuple_seq_as_map_impl_intern!($tyorig<(K, V) $(, $typaram: $bound)* >, BTreeMap<K, V>);
553        #[cfg(feature = "std")]
554        tuple_seq_as_map_impl_intern!($tyorig<(K, V) $(, $typaram: $bound)* >, HashMap<K, V>);
555    }
556}
557foreach_seq!(tuple_seq_as_map_impl, (K, V));
558tuple_seq_as_map_impl!(Option<(K, V)>);
559
560macro_rules! tuple_seq_as_map_arr {
561    ($tyorig:ty, $ty:ident <K, V>) => {
562        #[allow(clippy::implicit_hasher)]
563        impl<K, KAs, V, VAs, const N: usize> SerializeAs<$tyorig> for $ty<KAs, VAs>
564        where
565            KAs: SerializeAs<K>,
566            VAs: SerializeAs<V>,
567        {
568            fn serialize_as<S>(source: &$tyorig, serializer: S) -> Result<S::Ok, S::Error>
569            where
570                S: Serializer,
571            {
572                serializer.collect_map(source.iter().map(|(k, v)| {
573                    (
574                        SerializeAsWrap::<K, KAs>::new(k),
575                        SerializeAsWrap::<V, VAs>::new(v),
576                    )
577                }))
578            }
579        }
580    };
581}
582tuple_seq_as_map_arr!([(K, V); N], Map<K, V>);
583#[cfg(feature = "alloc")]
584tuple_seq_as_map_arr!([(K, V); N], BTreeMap<K, V>);
585#[cfg(feature = "std")]
586tuple_seq_as_map_arr!([(K, V); N], HashMap<K, V>);
587
588// endregion
589///////////////////////////////////////////////////////////////////////////////
590// region: Conversion types which cause different serialization behavior
591
592impl<T> SerializeAs<T> for Same
593where
594    T: Serialize + ?Sized,
595{
596    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
597    where
598        S: Serializer,
599    {
600        source.serialize(serializer)
601    }
602}
603
604impl<T> SerializeAs<T> for DisplayFromStr
605where
606    T: Display,
607{
608    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
609    where
610        S: Serializer,
611    {
612        serializer.collect_str(source)
613    }
614}
615
616impl<T, H, F> SerializeAs<T> for IfIsHumanReadable<H, F>
617where
618    T: ?Sized,
619    H: SerializeAs<T>,
620    F: SerializeAs<T>,
621{
622    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
623    where
624        S: Serializer,
625    {
626        if serializer.is_human_readable() {
627            H::serialize_as(source, serializer)
628        } else {
629            F::serialize_as(source, serializer)
630        }
631    }
632}
633
634impl<T> SerializeAs<Option<T>> for NoneAsEmptyString
635where
636    T: Display,
637{
638    fn serialize_as<S>(source: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
639    where
640        S: Serializer,
641    {
642        if let Some(value) = source {
643            serializer.collect_str(value)
644        } else {
645            serializer.serialize_str("")
646        }
647    }
648}
649
650#[cfg(feature = "alloc")]
651impl<T, TAs> SerializeAs<T> for DefaultOnError<TAs>
652where
653    TAs: SerializeAs<T>,
654{
655    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
656    where
657        S: Serializer,
658    {
659        TAs::serialize_as(source, serializer)
660    }
661}
662
663#[cfg(feature = "alloc")]
664impl SerializeAs<Vec<u8>> for BytesOrString {
665    fn serialize_as<S>(source: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
666    where
667        S: Serializer,
668    {
669        source.serialize(serializer)
670    }
671}
672
673impl<SEPARATOR, I, T> SerializeAs<I> for StringWithSeparator<SEPARATOR, T>
674where
675    SEPARATOR: formats::Separator,
676    for<'x> &'x I: IntoIterator<Item = &'x T>,
677    T: Display,
678    // This set of bounds is enough to make the function compile but has inference issues
679    // making it unusable at the moment.
680    // https://github.com/rust-lang/rust/issues/89196#issuecomment-932024770
681    // for<'x> &'x I: IntoIterator,
682    // for<'x> <&'x I as IntoIterator>::Item: Display,
683{
684    fn serialize_as<S>(source: &I, serializer: S) -> Result<S::Ok, S::Error>
685    where
686        S: Serializer,
687    {
688        pub(crate) struct DisplayWithSeparator<'a, I, SEPARATOR>(&'a I, PhantomData<SEPARATOR>);
689
690        impl<'a, I, SEPARATOR> DisplayWithSeparator<'a, I, SEPARATOR> {
691            pub(crate) fn new(iter: &'a I) -> Self {
692                Self(iter, PhantomData)
693            }
694        }
695
696        impl<'a, I, SEPARATOR> Display for DisplayWithSeparator<'a, I, SEPARATOR>
697        where
698            SEPARATOR: formats::Separator,
699            &'a I: IntoIterator,
700            <&'a I as IntoIterator>::Item: Display,
701        {
702            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
703                let mut iter = self.0.into_iter();
704
705                if let Some(first) = iter.next() {
706                    first.fmt(f)?;
707                }
708                for elem in iter {
709                    f.write_str(SEPARATOR::separator())?;
710                    elem.fmt(f)?;
711                }
712
713                Ok(())
714            }
715        }
716
717        serializer.collect_str(&DisplayWithSeparator::<I, SEPARATOR>::new(source))
718    }
719}
720
721macro_rules! use_signed_duration {
722    (
723        $main_trait:ident $internal_trait:ident =>
724        {
725            $ty:ty =>
726            $({
727                $format:ty, $strictness:ty =>
728                $($tbound:ident: $bound:ident $(,)?)*
729            })*
730        }
731    ) => {
732        $(
733            impl<$($tbound,)*> SerializeAs<$ty> for $main_trait<$format, $strictness>
734            where
735                $($tbound: $bound,)*
736            {
737                fn serialize_as<S>(source: &$ty, serializer: S) -> Result<S::Ok, S::Error>
738                where
739                    S: Serializer,
740                {
741                    $internal_trait::<$format, $strictness>::serialize_as(
742                        &DurationSigned::from(source),
743                        serializer,
744                    )
745                }
746            }
747        )*
748    };
749    (
750        $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
751    ) => {
752        $( use_signed_duration!($main_trait $internal_trait => $rest); )+
753    };
754}
755
756use_signed_duration!(
757    DurationSeconds DurationSeconds,
758    DurationMilliSeconds DurationMilliSeconds,
759    DurationMicroSeconds DurationMicroSeconds,
760    DurationNanoSeconds DurationNanoSeconds,
761    => {
762        Duration =>
763        {u64, STRICTNESS => STRICTNESS: Strictness}
764        {f64, STRICTNESS => STRICTNESS: Strictness}
765    }
766);
767#[cfg(feature = "alloc")]
768use_signed_duration!(
769    DurationSeconds DurationSeconds,
770    DurationMilliSeconds DurationMilliSeconds,
771    DurationMicroSeconds DurationMicroSeconds,
772    DurationNanoSeconds DurationNanoSeconds,
773    => {
774        Duration =>
775        {String, STRICTNESS => STRICTNESS: Strictness}
776    }
777);
778use_signed_duration!(
779    DurationSecondsWithFrac DurationSecondsWithFrac,
780    DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
781    DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
782    DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
783    => {
784        Duration =>
785        {f64, STRICTNESS => STRICTNESS: Strictness}
786    }
787);
788#[cfg(feature = "alloc")]
789use_signed_duration!(
790    DurationSecondsWithFrac DurationSecondsWithFrac,
791    DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
792    DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
793    DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
794    => {
795        Duration =>
796        {String, STRICTNESS => STRICTNESS: Strictness}
797    }
798);
799
800#[cfg(feature = "std")]
801use_signed_duration!(
802    TimestampSeconds DurationSeconds,
803    TimestampMilliSeconds DurationMilliSeconds,
804    TimestampMicroSeconds DurationMicroSeconds,
805    TimestampNanoSeconds DurationNanoSeconds,
806    => {
807        SystemTime =>
808        {i64, STRICTNESS => STRICTNESS: Strictness}
809        {f64, STRICTNESS => STRICTNESS: Strictness}
810        {String, STRICTNESS => STRICTNESS: Strictness}
811    }
812);
813#[cfg(feature = "std")]
814use_signed_duration!(
815    TimestampSecondsWithFrac DurationSecondsWithFrac,
816    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
817    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
818    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
819    => {
820        SystemTime =>
821        {f64, STRICTNESS => STRICTNESS: Strictness}
822        {String, STRICTNESS => STRICTNESS: Strictness}
823    }
824);
825
826impl<T, U> SerializeAs<T> for DefaultOnNull<U>
827where
828    U: SerializeAs<T>,
829{
830    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
831    where
832        S: Serializer,
833    {
834        serializer.serialize_some(&SerializeAsWrap::<T, U>::new(source))
835    }
836}
837
838impl SerializeAs<&[u8]> for Bytes {
839    fn serialize_as<S>(bytes: &&[u8], serializer: S) -> Result<S::Ok, S::Error>
840    where
841        S: Serializer,
842    {
843        serializer.serialize_bytes(bytes)
844    }
845}
846
847#[cfg(feature = "alloc")]
848impl SerializeAs<Vec<u8>> for Bytes {
849    fn serialize_as<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
850    where
851        S: Serializer,
852    {
853        serializer.serialize_bytes(bytes)
854    }
855}
856
857#[cfg(feature = "alloc")]
858impl SerializeAs<Box<[u8]>> for Bytes {
859    fn serialize_as<S>(bytes: &Box<[u8]>, serializer: S) -> Result<S::Ok, S::Error>
860    where
861        S: Serializer,
862    {
863        serializer.serialize_bytes(bytes)
864    }
865}
866
867#[cfg(feature = "alloc")]
868impl<'a> SerializeAs<Cow<'a, [u8]>> for Bytes {
869    fn serialize_as<S>(bytes: &Cow<'a, [u8]>, serializer: S) -> Result<S::Ok, S::Error>
870    where
871        S: Serializer,
872    {
873        serializer.serialize_bytes(bytes)
874    }
875}
876
877impl<const N: usize> SerializeAs<[u8; N]> for Bytes {
878    fn serialize_as<S>(bytes: &[u8; N], serializer: S) -> Result<S::Ok, S::Error>
879    where
880        S: Serializer,
881    {
882        serializer.serialize_bytes(bytes)
883    }
884}
885
886impl<const N: usize> SerializeAs<&[u8; N]> for Bytes {
887    fn serialize_as<S>(bytes: &&[u8; N], serializer: S) -> Result<S::Ok, S::Error>
888    where
889        S: Serializer,
890    {
891        serializer.serialize_bytes(*bytes)
892    }
893}
894
895#[cfg(feature = "alloc")]
896impl<const N: usize> SerializeAs<Box<[u8; N]>> for Bytes {
897    fn serialize_as<S>(bytes: &Box<[u8; N]>, serializer: S) -> Result<S::Ok, S::Error>
898    where
899        S: Serializer,
900    {
901        serializer.serialize_bytes(&**bytes)
902    }
903}
904
905#[cfg(feature = "alloc")]
906impl<'a, const N: usize> SerializeAs<Cow<'a, [u8; N]>> for Bytes {
907    fn serialize_as<S>(bytes: &Cow<'a, [u8; N]>, serializer: S) -> Result<S::Ok, S::Error>
908    where
909        S: Serializer,
910    {
911        serializer.serialize_bytes(bytes.as_ref())
912    }
913}
914
915#[cfg(feature = "alloc")]
916impl<T, U> SerializeAs<Vec<T>> for OneOrMany<U, formats::PreferOne>
917where
918    U: SerializeAs<T>,
919{
920    fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
921    where
922        S: Serializer,
923    {
924        match source.len() {
925            1 => SerializeAsWrap::<T, U>::new(source.iter().next().expect("Cannot be empty"))
926                .serialize(serializer),
927            _ => SerializeAsWrap::<Vec<T>, Vec<U>>::new(source).serialize(serializer),
928        }
929    }
930}
931
932#[cfg(feature = "alloc")]
933impl<T, U> SerializeAs<Vec<T>> for OneOrMany<U, formats::PreferMany>
934where
935    U: SerializeAs<T>,
936{
937    fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
938    where
939        S: Serializer,
940    {
941        SerializeAsWrap::<Vec<T>, Vec<U>>::new(source).serialize(serializer)
942    }
943}
944
945#[cfg(feature = "alloc")]
946impl<T, TAs1> SerializeAs<T> for PickFirst<(TAs1,)>
947where
948    TAs1: SerializeAs<T>,
949{
950    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
951    where
952        S: Serializer,
953    {
954        SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
955    }
956}
957
958#[cfg(feature = "alloc")]
959impl<T, TAs1, TAs2> SerializeAs<T> for PickFirst<(TAs1, TAs2)>
960where
961    TAs1: SerializeAs<T>,
962{
963    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
964    where
965        S: Serializer,
966    {
967        SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
968    }
969}
970
971#[cfg(feature = "alloc")]
972impl<T, TAs1, TAs2, TAs3> SerializeAs<T> for PickFirst<(TAs1, TAs2, TAs3)>
973where
974    TAs1: SerializeAs<T>,
975{
976    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
977    where
978        S: Serializer,
979    {
980        SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
981    }
982}
983
984#[cfg(feature = "alloc")]
985impl<T, TAs1, TAs2, TAs3, TAs4> SerializeAs<T> for PickFirst<(TAs1, TAs2, TAs3, TAs4)>
986where
987    TAs1: SerializeAs<T>,
988{
989    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
990    where
991        S: Serializer,
992    {
993        SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
994    }
995}
996
997impl<T, U> SerializeAs<T> for FromInto<U>
998where
999    T: Into<U> + Clone,
1000    U: Serialize,
1001{
1002    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
1003    where
1004        S: Serializer,
1005    {
1006        source.clone().into().serialize(serializer)
1007    }
1008}
1009
1010impl<T, U> SerializeAs<T> for TryFromInto<U>
1011where
1012    T: TryInto<U> + Clone,
1013    <T as TryInto<U>>::Error: Display,
1014    U: Serialize,
1015{
1016    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
1017    where
1018        S: Serializer,
1019    {
1020        source
1021            .clone()
1022            .try_into()
1023            .map_err(S::Error::custom)?
1024            .serialize(serializer)
1025    }
1026}
1027
1028impl<T, U> SerializeAs<T> for FromIntoRef<U>
1029where
1030    for<'a> &'a T: Into<U>,
1031    U: Serialize,
1032{
1033    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
1034    where
1035        S: Serializer,
1036    {
1037        source.into().serialize(serializer)
1038    }
1039}
1040
1041impl<T, U> SerializeAs<T> for TryFromIntoRef<U>
1042where
1043    for<'a> &'a T: TryInto<U>,
1044    for<'a> <&'a T as TryInto<U>>::Error: Display,
1045    U: Serialize,
1046{
1047    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
1048    where
1049        S: Serializer,
1050    {
1051        source
1052            .try_into()
1053            .map_err(S::Error::custom)?
1054            .serialize(serializer)
1055    }
1056}
1057
1058#[cfg(feature = "alloc")]
1059impl<'a> SerializeAs<Cow<'a, str>> for BorrowCow {
1060    fn serialize_as<S>(source: &Cow<'a, str>, serializer: S) -> Result<S::Ok, S::Error>
1061    where
1062        S: Serializer,
1063    {
1064        serializer.serialize_str(source)
1065    }
1066}
1067
1068#[cfg(feature = "alloc")]
1069impl<'a> SerializeAs<Cow<'a, [u8]>> for BorrowCow {
1070    fn serialize_as<S>(value: &Cow<'a, [u8]>, serializer: S) -> Result<S::Ok, S::Error>
1071    where
1072        S: Serializer,
1073    {
1074        serializer.collect_seq(value.iter())
1075    }
1076}
1077
1078#[cfg(feature = "alloc")]
1079impl<'a, const N: usize> SerializeAs<Cow<'a, [u8; N]>> for BorrowCow {
1080    fn serialize_as<S>(value: &Cow<'a, [u8; N]>, serializer: S) -> Result<S::Ok, S::Error>
1081    where
1082        S: Serializer,
1083    {
1084        serializer.collect_seq(value.iter())
1085    }
1086}
1087
1088impl<STRICTNESS: Strictness> SerializeAs<bool> for BoolFromInt<STRICTNESS> {
1089    fn serialize_as<S>(source: &bool, serializer: S) -> Result<S::Ok, S::Error>
1090    where
1091        S: Serializer,
1092    {
1093        serializer.serialize_u8(u8::from(*source))
1094    }
1095}
1096
1097// endregion