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(ref v) => Bound::Included(SerializeAsWrap::<T, U>::new(v)),
186            Bound::Excluded(ref 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: Collection Types (e.g., Maps, Sets, Vec)
348
349macro_rules! seq_impl {
350    ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident )* >) => {
351        impl<T, U $(, $typaram)*> SerializeAs<$ty<T $(, $typaram)*>> for $ty<U $(, $typaram)*>
352        where
353            U: SerializeAs<T>,
354            $(T: ?Sized + $tbound1 $(+ $tbound2)*,)*
355            $($typaram: ?Sized + $bound,)*
356        {
357            fn serialize_as<S>(source: &$ty<T $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
358            where
359                S: Serializer,
360            {
361                serializer.collect_seq(source.iter().map(|item| SerializeAsWrap::<T, U>::new(item)))
362            }
363        }
364    }
365}
366foreach_seq!(seq_impl);
367
368#[cfg(feature = "alloc")]
369macro_rules! map_impl {
370    ($ty:ident < K, V $(, $typaram:ident : $bound:ident)* >) => {
371        impl<K, KU, V, VU $(, $typaram)*> SerializeAs<$ty<K, V $(, $typaram)*>> for $ty<KU, VU $(, $typaram)*>
372        where
373            KU: SerializeAs<K>,
374            VU: SerializeAs<V>,
375            $($typaram: ?Sized + $bound,)*
376        {
377            fn serialize_as<S>(source: &$ty<K, V $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
378            where
379                S: Serializer,
380            {
381                serializer.collect_map(source.iter().map(|(k, v)| (SerializeAsWrap::<K, KU>::new(k), SerializeAsWrap::<V, VU>::new(v))))
382            }
383        }
384    }
385}
386foreach_map!(map_impl);
387
388macro_rules! tuple_impl {
389    ($len:literal $($n:tt $t:ident $tas:ident)+) => {
390        impl<$($t, $tas,)+> SerializeAs<($($t,)+)> for ($($tas,)+)
391        where
392            $($tas: SerializeAs<$t>,)+
393        {
394            fn serialize_as<S>(tuple: &($($t,)+), serializer: S) -> Result<S::Ok, S::Error>
395            where
396                S: Serializer,
397            {
398                use serde::ser::SerializeTuple;
399                let mut tup = serializer.serialize_tuple($len)?;
400                $(
401                    tup.serialize_element(&SerializeAsWrap::<$t, $tas>::new(&tuple.$n))?;
402                )+
403                tup.end()
404            }
405        }
406    };
407}
408
409tuple_impl!(1 0 T0 As0);
410tuple_impl!(2 0 T0 As0 1 T1 As1);
411tuple_impl!(3 0 T0 As0 1 T1 As1 2 T2 As2);
412tuple_impl!(4 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3);
413tuple_impl!(5 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4);
414tuple_impl!(6 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5);
415tuple_impl!(7 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6);
416tuple_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);
417tuple_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);
418tuple_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);
419tuple_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);
420tuple_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);
421tuple_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);
422tuple_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);
423tuple_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);
424tuple_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);
425
426#[cfg(feature = "alloc")]
427macro_rules! map_as_tuple_seq_intern {
428    ($tyorig:ident < K, V $(, $typaram:ident : $bound:ident)* >, $ty:ident <(K, V)>) => {
429        impl<K, KAs, V, VAs $(, $typaram)*> SerializeAs<$tyorig<K, V $(, $typaram)*>> for $ty<(KAs, VAs)>
430        where
431            KAs: SerializeAs<K>,
432            VAs: SerializeAs<V>,
433            $($typaram: ?Sized + $bound,)*
434        {
435            fn serialize_as<S>(source: &$tyorig<K, V $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
436            where
437                S: Serializer,
438            {
439                serializer.collect_seq(source.iter().map(|(k, v)| {
440                    (
441                        SerializeAsWrap::<K, KAs>::new(k),
442                        SerializeAsWrap::<V, VAs>::new(v),
443                    )
444                }))
445            }
446        }
447    };
448}
449#[cfg(feature = "alloc")]
450macro_rules! map_as_tuple_seq {
451    ($tyorig:ident < K, V $(, $typaram:ident : $bound:ident)* >) => {
452        map_as_tuple_seq_intern!($tyorig<K, V $(, $typaram: $bound)* >, Seq<(K, V)>);
453        #[cfg(feature = "alloc")]
454        map_as_tuple_seq_intern!($tyorig<K, V $(, $typaram: $bound)* >, Vec<(K, V)>);
455    }
456}
457foreach_map!(map_as_tuple_seq);
458
459macro_rules! tuple_seq_as_map_impl_intern {
460    ($tyorig:ident < (K, V) $(, $typaram:ident : $bound:ident)* >, $ty:ident <K, V>) => {
461        #[allow(clippy::implicit_hasher)]
462        impl<K, KAs, V, VAs $(, $typaram)*> SerializeAs<$tyorig<(K, V) $(, $typaram)*>> for $ty<KAs, VAs>
463        where
464            KAs: SerializeAs<K>,
465            VAs: SerializeAs<V>,
466            $($typaram: ?Sized + $bound,)*
467        {
468            fn serialize_as<S>(source: &$tyorig<(K, V) $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
469            where
470                S: Serializer,
471            {
472                serializer.collect_map(source.iter().map(|(k, v)| {
473                    (
474                        SerializeAsWrap::<K, KAs>::new(k),
475                        SerializeAsWrap::<V, VAs>::new(v),
476                    )
477                }))
478            }
479        }
480    };
481}
482macro_rules! tuple_seq_as_map_impl {
483    ($tyorig:ident < (K, V) $(, $typaram:ident : $bound:ident)* >) => {
484        tuple_seq_as_map_impl_intern!($tyorig<(K, V) $(, $typaram: $bound)* >, Map<K, V>);
485        #[cfg(feature = "alloc")]
486        tuple_seq_as_map_impl_intern!($tyorig<(K, V) $(, $typaram: $bound)* >, BTreeMap<K, V>);
487        #[cfg(feature = "std")]
488        tuple_seq_as_map_impl_intern!($tyorig<(K, V) $(, $typaram: $bound)* >, HashMap<K, V>);
489    }
490}
491foreach_seq!(tuple_seq_as_map_impl, (K, V));
492tuple_seq_as_map_impl!(Option<(K, V)>);
493
494macro_rules! tuple_seq_as_map_arr {
495    ($tyorig:ty, $ty:ident <K, V>) => {
496        #[allow(clippy::implicit_hasher)]
497        impl<K, KAs, V, VAs, const N: usize> SerializeAs<$tyorig> for $ty<KAs, VAs>
498        where
499            KAs: SerializeAs<K>,
500            VAs: SerializeAs<V>,
501        {
502            fn serialize_as<S>(source: &$tyorig, serializer: S) -> Result<S::Ok, S::Error>
503            where
504                S: Serializer,
505            {
506                serializer.collect_map(source.iter().map(|(k, v)| {
507                    (
508                        SerializeAsWrap::<K, KAs>::new(k),
509                        SerializeAsWrap::<V, VAs>::new(v),
510                    )
511                }))
512            }
513        }
514    };
515}
516tuple_seq_as_map_arr!([(K, V); N], Map<K, V>);
517#[cfg(feature = "alloc")]
518tuple_seq_as_map_arr!([(K, V); N], BTreeMap<K, V>);
519#[cfg(feature = "std")]
520tuple_seq_as_map_arr!([(K, V); N], HashMap<K, V>);
521
522// endregion
523///////////////////////////////////////////////////////////////////////////////
524// region: Conversion types which cause different serialization behavior
525
526impl<T> SerializeAs<T> for Same
527where
528    T: Serialize + ?Sized,
529{
530    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
531    where
532        S: Serializer,
533    {
534        source.serialize(serializer)
535    }
536}
537
538impl<T> SerializeAs<T> for DisplayFromStr
539where
540    T: Display,
541{
542    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
543    where
544        S: Serializer,
545    {
546        serializer.collect_str(source)
547    }
548}
549
550impl<T, H, F> SerializeAs<T> for IfIsHumanReadable<H, F>
551where
552    T: ?Sized,
553    H: SerializeAs<T>,
554    F: SerializeAs<T>,
555{
556    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
557    where
558        S: Serializer,
559    {
560        if serializer.is_human_readable() {
561            H::serialize_as(source, serializer)
562        } else {
563            F::serialize_as(source, serializer)
564        }
565    }
566}
567
568impl<T> SerializeAs<Option<T>> for NoneAsEmptyString
569where
570    T: Display,
571{
572    fn serialize_as<S>(source: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
573    where
574        S: Serializer,
575    {
576        if let Some(value) = source {
577            serializer.collect_str(value)
578        } else {
579            serializer.serialize_str("")
580        }
581    }
582}
583
584#[cfg(feature = "alloc")]
585impl<T, TAs> SerializeAs<T> for DefaultOnError<TAs>
586where
587    TAs: SerializeAs<T>,
588{
589    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
590    where
591        S: Serializer,
592    {
593        TAs::serialize_as(source, serializer)
594    }
595}
596
597#[cfg(feature = "alloc")]
598impl SerializeAs<Vec<u8>> for BytesOrString {
599    fn serialize_as<S>(source: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
600    where
601        S: Serializer,
602    {
603        source.serialize(serializer)
604    }
605}
606
607impl<SEPARATOR, I, T> SerializeAs<I> for StringWithSeparator<SEPARATOR, T>
608where
609    SEPARATOR: formats::Separator,
610    for<'x> &'x I: IntoIterator<Item = &'x T>,
611    T: Display,
612    // This set of bounds is enough to make the function compile but has inference issues
613    // making it unusable at the moment.
614    // https://github.com/rust-lang/rust/issues/89196#issuecomment-932024770
615    // for<'x> &'x I: IntoIterator,
616    // for<'x> <&'x I as IntoIterator>::Item: Display,
617{
618    fn serialize_as<S>(source: &I, serializer: S) -> Result<S::Ok, S::Error>
619    where
620        S: Serializer,
621    {
622        pub(crate) struct DisplayWithSeparator<'a, I, SEPARATOR>(&'a I, PhantomData<SEPARATOR>);
623
624        impl<'a, I, SEPARATOR> DisplayWithSeparator<'a, I, SEPARATOR> {
625            pub(crate) fn new(iter: &'a I) -> Self {
626                Self(iter, PhantomData)
627            }
628        }
629
630        impl<'a, I, SEPARATOR> Display for DisplayWithSeparator<'a, I, SEPARATOR>
631        where
632            SEPARATOR: formats::Separator,
633            &'a I: IntoIterator,
634            <&'a I as IntoIterator>::Item: Display,
635        {
636            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
637                let mut iter = self.0.into_iter();
638
639                if let Some(first) = iter.next() {
640                    first.fmt(f)?;
641                }
642                for elem in iter {
643                    f.write_str(SEPARATOR::separator())?;
644                    elem.fmt(f)?;
645                }
646
647                Ok(())
648            }
649        }
650
651        serializer.collect_str(&DisplayWithSeparator::<I, SEPARATOR>::new(source))
652    }
653}
654
655macro_rules! use_signed_duration {
656    (
657        $main_trait:ident $internal_trait:ident =>
658        {
659            $ty:ty =>
660            $({
661                $format:ty, $strictness:ty =>
662                $($tbound:ident: $bound:ident $(,)?)*
663            })*
664        }
665    ) => {
666        $(
667            impl<$($tbound,)*> SerializeAs<$ty> for $main_trait<$format, $strictness>
668            where
669                $($tbound: $bound,)*
670            {
671                fn serialize_as<S>(source: &$ty, serializer: S) -> Result<S::Ok, S::Error>
672                where
673                    S: Serializer,
674                {
675                    $internal_trait::<$format, $strictness>::serialize_as(
676                        &DurationSigned::from(source),
677                        serializer,
678                    )
679                }
680            }
681        )*
682    };
683    (
684        $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
685    ) => {
686        $( use_signed_duration!($main_trait $internal_trait => $rest); )+
687    };
688}
689
690use_signed_duration!(
691    DurationSeconds DurationSeconds,
692    DurationMilliSeconds DurationMilliSeconds,
693    DurationMicroSeconds DurationMicroSeconds,
694    DurationNanoSeconds DurationNanoSeconds,
695    => {
696        Duration =>
697        {u64, STRICTNESS => STRICTNESS: Strictness}
698        {f64, STRICTNESS => STRICTNESS: Strictness}
699    }
700);
701#[cfg(feature = "alloc")]
702use_signed_duration!(
703    DurationSeconds DurationSeconds,
704    DurationMilliSeconds DurationMilliSeconds,
705    DurationMicroSeconds DurationMicroSeconds,
706    DurationNanoSeconds DurationNanoSeconds,
707    => {
708        Duration =>
709        {String, STRICTNESS => STRICTNESS: Strictness}
710    }
711);
712use_signed_duration!(
713    DurationSecondsWithFrac DurationSecondsWithFrac,
714    DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
715    DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
716    DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
717    => {
718        Duration =>
719        {f64, STRICTNESS => STRICTNESS: Strictness}
720    }
721);
722#[cfg(feature = "alloc")]
723use_signed_duration!(
724    DurationSecondsWithFrac DurationSecondsWithFrac,
725    DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
726    DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
727    DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
728    => {
729        Duration =>
730        {String, STRICTNESS => STRICTNESS: Strictness}
731    }
732);
733
734#[cfg(feature = "std")]
735use_signed_duration!(
736    TimestampSeconds DurationSeconds,
737    TimestampMilliSeconds DurationMilliSeconds,
738    TimestampMicroSeconds DurationMicroSeconds,
739    TimestampNanoSeconds DurationNanoSeconds,
740    => {
741        SystemTime =>
742        {i64, STRICTNESS => STRICTNESS: Strictness}
743        {f64, STRICTNESS => STRICTNESS: Strictness}
744        {String, STRICTNESS => STRICTNESS: Strictness}
745    }
746);
747#[cfg(feature = "std")]
748use_signed_duration!(
749    TimestampSecondsWithFrac DurationSecondsWithFrac,
750    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
751    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
752    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
753    => {
754        SystemTime =>
755        {f64, STRICTNESS => STRICTNESS: Strictness}
756        {String, STRICTNESS => STRICTNESS: Strictness}
757    }
758);
759
760impl<T, U> SerializeAs<T> for DefaultOnNull<U>
761where
762    U: SerializeAs<T>,
763{
764    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
765    where
766        S: Serializer,
767    {
768        serializer.serialize_some(&SerializeAsWrap::<T, U>::new(source))
769    }
770}
771
772impl SerializeAs<&[u8]> for Bytes {
773    fn serialize_as<S>(bytes: &&[u8], serializer: S) -> Result<S::Ok, S::Error>
774    where
775        S: Serializer,
776    {
777        serializer.serialize_bytes(bytes)
778    }
779}
780
781#[cfg(feature = "alloc")]
782impl SerializeAs<Vec<u8>> for Bytes {
783    fn serialize_as<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
784    where
785        S: Serializer,
786    {
787        serializer.serialize_bytes(bytes)
788    }
789}
790
791#[cfg(feature = "alloc")]
792impl SerializeAs<Box<[u8]>> for Bytes {
793    fn serialize_as<S>(bytes: &Box<[u8]>, serializer: S) -> Result<S::Ok, S::Error>
794    where
795        S: Serializer,
796    {
797        serializer.serialize_bytes(bytes)
798    }
799}
800
801#[cfg(feature = "alloc")]
802impl<'a> SerializeAs<Cow<'a, [u8]>> for Bytes {
803    fn serialize_as<S>(bytes: &Cow<'a, [u8]>, serializer: S) -> Result<S::Ok, S::Error>
804    where
805        S: Serializer,
806    {
807        serializer.serialize_bytes(bytes)
808    }
809}
810
811impl<const N: usize> SerializeAs<[u8; N]> for Bytes {
812    fn serialize_as<S>(bytes: &[u8; N], serializer: S) -> Result<S::Ok, S::Error>
813    where
814        S: Serializer,
815    {
816        serializer.serialize_bytes(bytes)
817    }
818}
819
820impl<const N: usize> SerializeAs<&[u8; N]> for Bytes {
821    fn serialize_as<S>(bytes: &&[u8; N], serializer: S) -> Result<S::Ok, S::Error>
822    where
823        S: Serializer,
824    {
825        serializer.serialize_bytes(*bytes)
826    }
827}
828
829#[cfg(feature = "alloc")]
830impl<const N: usize> SerializeAs<Box<[u8; N]>> for Bytes {
831    fn serialize_as<S>(bytes: &Box<[u8; N]>, serializer: S) -> Result<S::Ok, S::Error>
832    where
833        S: Serializer,
834    {
835        serializer.serialize_bytes(&**bytes)
836    }
837}
838
839#[cfg(feature = "alloc")]
840impl<'a, const N: usize> SerializeAs<Cow<'a, [u8; N]>> for Bytes {
841    fn serialize_as<S>(bytes: &Cow<'a, [u8; N]>, serializer: S) -> Result<S::Ok, S::Error>
842    where
843        S: Serializer,
844    {
845        serializer.serialize_bytes(bytes.as_ref())
846    }
847}
848
849#[cfg(feature = "alloc")]
850impl<T, U> SerializeAs<Vec<T>> for OneOrMany<U, formats::PreferOne>
851where
852    U: SerializeAs<T>,
853{
854    fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
855    where
856        S: Serializer,
857    {
858        match source.len() {
859            1 => SerializeAsWrap::<T, U>::new(source.iter().next().expect("Cannot be empty"))
860                .serialize(serializer),
861            _ => SerializeAsWrap::<Vec<T>, Vec<U>>::new(source).serialize(serializer),
862        }
863    }
864}
865
866#[cfg(feature = "alloc")]
867impl<T, U> SerializeAs<Vec<T>> for OneOrMany<U, formats::PreferMany>
868where
869    U: SerializeAs<T>,
870{
871    fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
872    where
873        S: Serializer,
874    {
875        SerializeAsWrap::<Vec<T>, Vec<U>>::new(source).serialize(serializer)
876    }
877}
878
879#[cfg(feature = "alloc")]
880impl<T, TAs1> SerializeAs<T> for PickFirst<(TAs1,)>
881where
882    TAs1: SerializeAs<T>,
883{
884    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
885    where
886        S: Serializer,
887    {
888        SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
889    }
890}
891
892#[cfg(feature = "alloc")]
893impl<T, TAs1, TAs2> SerializeAs<T> for PickFirst<(TAs1, TAs2)>
894where
895    TAs1: SerializeAs<T>,
896{
897    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
898    where
899        S: Serializer,
900    {
901        SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
902    }
903}
904
905#[cfg(feature = "alloc")]
906impl<T, TAs1, TAs2, TAs3> SerializeAs<T> for PickFirst<(TAs1, TAs2, TAs3)>
907where
908    TAs1: SerializeAs<T>,
909{
910    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
911    where
912        S: Serializer,
913    {
914        SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
915    }
916}
917
918#[cfg(feature = "alloc")]
919impl<T, TAs1, TAs2, TAs3, TAs4> SerializeAs<T> for PickFirst<(TAs1, TAs2, TAs3, TAs4)>
920where
921    TAs1: SerializeAs<T>,
922{
923    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
924    where
925        S: Serializer,
926    {
927        SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
928    }
929}
930
931impl<T, U> SerializeAs<T> for FromInto<U>
932where
933    T: Into<U> + Clone,
934    U: Serialize,
935{
936    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
937    where
938        S: Serializer,
939    {
940        source.clone().into().serialize(serializer)
941    }
942}
943
944impl<T, U> SerializeAs<T> for TryFromInto<U>
945where
946    T: TryInto<U> + Clone,
947    <T as TryInto<U>>::Error: Display,
948    U: Serialize,
949{
950    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
951    where
952        S: Serializer,
953    {
954        source
955            .clone()
956            .try_into()
957            .map_err(S::Error::custom)?
958            .serialize(serializer)
959    }
960}
961
962impl<T, U> SerializeAs<T> for FromIntoRef<U>
963where
964    for<'a> &'a T: Into<U>,
965    U: Serialize,
966{
967    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
968    where
969        S: Serializer,
970    {
971        source.into().serialize(serializer)
972    }
973}
974
975impl<T, U> SerializeAs<T> for TryFromIntoRef<U>
976where
977    for<'a> &'a T: TryInto<U>,
978    for<'a> <&'a T as TryInto<U>>::Error: Display,
979    U: Serialize,
980{
981    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
982    where
983        S: Serializer,
984    {
985        source
986            .try_into()
987            .map_err(S::Error::custom)?
988            .serialize(serializer)
989    }
990}
991
992#[cfg(feature = "alloc")]
993impl<'a> SerializeAs<Cow<'a, str>> for BorrowCow {
994    fn serialize_as<S>(source: &Cow<'a, str>, serializer: S) -> Result<S::Ok, S::Error>
995    where
996        S: Serializer,
997    {
998        serializer.serialize_str(source)
999    }
1000}
1001
1002#[cfg(feature = "alloc")]
1003impl<'a> SerializeAs<Cow<'a, [u8]>> for BorrowCow {
1004    fn serialize_as<S>(value: &Cow<'a, [u8]>, serializer: S) -> Result<S::Ok, S::Error>
1005    where
1006        S: Serializer,
1007    {
1008        serializer.collect_seq(value.iter())
1009    }
1010}
1011
1012#[cfg(feature = "alloc")]
1013impl<'a, const N: usize> SerializeAs<Cow<'a, [u8; N]>> for BorrowCow {
1014    fn serialize_as<S>(value: &Cow<'a, [u8; N]>, serializer: S) -> Result<S::Ok, S::Error>
1015    where
1016        S: Serializer,
1017    {
1018        serializer.collect_seq(value.iter())
1019    }
1020}
1021
1022impl<STRICTNESS: Strictness> SerializeAs<bool> for BoolFromInt<STRICTNESS> {
1023    fn serialize_as<S>(source: &bool, serializer: S) -> Result<S::Ok, S::Error>
1024    where
1025        S: Serializer,
1026    {
1027        serializer.serialize_u8(u8::from(*source))
1028    }
1029}
1030
1031// endregion