serde/ser/
impls.rs

1use crate::lib::*;
2
3use crate::ser::{Error, Serialize, SerializeTuple, Serializer};
4
5////////////////////////////////////////////////////////////////////////////////
6
7macro_rules! primitive_impl {
8    ($ty:ident, $method:ident $($cast:tt)*) => {
9        impl Serialize for $ty {
10            #[inline]
11            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
12            where
13                S: Serializer,
14            {
15                serializer.$method(*self $($cast)*)
16            }
17        }
18    }
19}
20
21primitive_impl!(bool, serialize_bool);
22primitive_impl!(isize, serialize_i64 as i64);
23primitive_impl!(i8, serialize_i8);
24primitive_impl!(i16, serialize_i16);
25primitive_impl!(i32, serialize_i32);
26primitive_impl!(i64, serialize_i64);
27primitive_impl!(i128, serialize_i128);
28primitive_impl!(usize, serialize_u64 as u64);
29primitive_impl!(u8, serialize_u8);
30primitive_impl!(u16, serialize_u16);
31primitive_impl!(u32, serialize_u32);
32primitive_impl!(u64, serialize_u64);
33primitive_impl!(u128, serialize_u128);
34primitive_impl!(f32, serialize_f32);
35primitive_impl!(f64, serialize_f64);
36primitive_impl!(char, serialize_char);
37
38////////////////////////////////////////////////////////////////////////////////
39
40impl Serialize for str {
41    #[inline]
42    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
43    where
44        S: Serializer,
45    {
46        serializer.serialize_str(self)
47    }
48}
49
50#[cfg(any(feature = "std", feature = "alloc"))]
51#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
52impl Serialize for String {
53    #[inline]
54    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55    where
56        S: Serializer,
57    {
58        serializer.serialize_str(self)
59    }
60}
61
62impl<'a> Serialize for fmt::Arguments<'a> {
63    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
64    where
65        S: Serializer,
66    {
67        serializer.collect_str(self)
68    }
69}
70
71////////////////////////////////////////////////////////////////////////////////
72
73#[cfg(any(feature = "std", not(no_core_cstr)))]
74#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
75impl Serialize for CStr {
76    #[inline]
77    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78    where
79        S: Serializer,
80    {
81        serializer.serialize_bytes(self.to_bytes())
82    }
83}
84
85#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))]
86#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
87impl Serialize for CString {
88    #[inline]
89    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
90    where
91        S: Serializer,
92    {
93        serializer.serialize_bytes(self.to_bytes())
94    }
95}
96
97////////////////////////////////////////////////////////////////////////////////
98
99impl<T> Serialize for Option<T>
100where
101    T: Serialize,
102{
103    #[inline]
104    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
105    where
106        S: Serializer,
107    {
108        match *self {
109            Some(ref value) => serializer.serialize_some(value),
110            None => serializer.serialize_none(),
111        }
112    }
113}
114
115////////////////////////////////////////////////////////////////////////////////
116
117impl<T> Serialize for PhantomData<T>
118where
119    T: ?Sized,
120{
121    #[inline]
122    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
123    where
124        S: Serializer,
125    {
126        serializer.serialize_unit_struct("PhantomData")
127    }
128}
129
130////////////////////////////////////////////////////////////////////////////////
131
132// Does not require T: Serialize.
133impl<T> Serialize for [T; 0] {
134    #[inline]
135    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
136    where
137        S: Serializer,
138    {
139        tri!(serializer.serialize_tuple(0)).end()
140    }
141}
142
143macro_rules! array_impls {
144    ($($len:tt)+) => {
145        $(
146            impl<T> Serialize for [T; $len]
147            where
148                T: Serialize,
149            {
150                #[inline]
151                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
152                where
153                    S: Serializer,
154                {
155                    let mut seq = tri!(serializer.serialize_tuple($len));
156                    for e in self {
157                        tri!(seq.serialize_element(e));
158                    }
159                    seq.end()
160                }
161            }
162        )+
163    }
164}
165
166array_impls! {
167    01 02 03 04 05 06 07 08 09 10
168    11 12 13 14 15 16 17 18 19 20
169    21 22 23 24 25 26 27 28 29 30
170    31 32
171}
172
173////////////////////////////////////////////////////////////////////////////////
174
175impl<T> Serialize for [T]
176where
177    T: Serialize,
178{
179    #[inline]
180    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
181    where
182        S: Serializer,
183    {
184        serializer.collect_seq(self)
185    }
186}
187
188#[cfg(not(no_relaxed_trait_bounds))]
189macro_rules! seq_impl {
190    (
191        $(#[$attr:meta])*
192        $ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)*>
193    ) => {
194        $(#[$attr])*
195        impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
196        where
197            T: Serialize,
198        {
199            #[inline]
200            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
201            where
202                S: Serializer,
203            {
204                serializer.collect_seq(self)
205            }
206        }
207    }
208}
209
210#[cfg(no_relaxed_trait_bounds)]
211macro_rules! seq_impl {
212    (
213        $(#[$attr:meta])*
214        $ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)*>
215    ) => {
216        $(#[$attr])*
217        impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
218        where
219            T: Serialize $(+ $tbound1 $(+ $tbound2)*)*,
220            $($typaram: $bound,)*
221        {
222            #[inline]
223            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
224            where
225                S: Serializer,
226            {
227                serializer.collect_seq(self)
228            }
229        }
230    }
231}
232
233seq_impl! {
234    #[cfg(any(feature = "std", feature = "alloc"))]
235    #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
236    BinaryHeap<T: Ord>
237}
238
239seq_impl! {
240    #[cfg(any(feature = "std", feature = "alloc"))]
241    #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
242    BTreeSet<T: Ord>
243}
244
245seq_impl! {
246    #[cfg(feature = "std")]
247    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
248    HashSet<T: Eq + Hash, H: BuildHasher>
249}
250
251seq_impl! {
252    #[cfg(any(feature = "std", feature = "alloc"))]
253    #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
254    LinkedList<T>
255}
256
257seq_impl! {
258    #[cfg(any(feature = "std", feature = "alloc"))]
259    #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
260    Vec<T>
261}
262
263seq_impl! {
264    #[cfg(any(feature = "std", feature = "alloc"))]
265    #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
266    VecDeque<T>
267}
268
269////////////////////////////////////////////////////////////////////////////////
270
271impl<Idx> Serialize for Range<Idx>
272where
273    Idx: Serialize,
274{
275    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
276    where
277        S: Serializer,
278    {
279        use super::SerializeStruct;
280        let mut state = tri!(serializer.serialize_struct("Range", 2));
281        tri!(state.serialize_field("start", &self.start));
282        tri!(state.serialize_field("end", &self.end));
283        state.end()
284    }
285}
286
287////////////////////////////////////////////////////////////////////////////////
288
289impl<Idx> Serialize for RangeFrom<Idx>
290where
291    Idx: Serialize,
292{
293    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
294    where
295        S: Serializer,
296    {
297        use super::SerializeStruct;
298        let mut state = tri!(serializer.serialize_struct("RangeFrom", 1));
299        tri!(state.serialize_field("start", &self.start));
300        state.end()
301    }
302}
303
304////////////////////////////////////////////////////////////////////////////////
305
306impl<Idx> Serialize for RangeInclusive<Idx>
307where
308    Idx: Serialize,
309{
310    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
311    where
312        S: Serializer,
313    {
314        use super::SerializeStruct;
315        let mut state = tri!(serializer.serialize_struct("RangeInclusive", 2));
316        tri!(state.serialize_field("start", &self.start()));
317        tri!(state.serialize_field("end", &self.end()));
318        state.end()
319    }
320}
321
322////////////////////////////////////////////////////////////////////////////////
323
324impl<Idx> Serialize for RangeTo<Idx>
325where
326    Idx: Serialize,
327{
328    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
329    where
330        S: Serializer,
331    {
332        use super::SerializeStruct;
333        let mut state = tri!(serializer.serialize_struct("RangeTo", 1));
334        tri!(state.serialize_field("end", &self.end));
335        state.end()
336    }
337}
338
339////////////////////////////////////////////////////////////////////////////////
340
341impl<T> Serialize for Bound<T>
342where
343    T: Serialize,
344{
345    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
346    where
347        S: Serializer,
348    {
349        match *self {
350            Bound::Unbounded => serializer.serialize_unit_variant("Bound", 0, "Unbounded"),
351            Bound::Included(ref value) => {
352                serializer.serialize_newtype_variant("Bound", 1, "Included", value)
353            }
354            Bound::Excluded(ref value) => {
355                serializer.serialize_newtype_variant("Bound", 2, "Excluded", value)
356            }
357        }
358    }
359}
360
361////////////////////////////////////////////////////////////////////////////////
362
363impl Serialize for () {
364    #[inline]
365    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
366    where
367        S: Serializer,
368    {
369        serializer.serialize_unit()
370    }
371}
372
373#[cfg(feature = "unstable")]
374#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
375impl Serialize for ! {
376    fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
377    where
378        S: Serializer,
379    {
380        *self
381    }
382}
383
384////////////////////////////////////////////////////////////////////////////////
385
386macro_rules! tuple_impls {
387    ($($len:expr => ($($n:tt $name:ident)+))+) => {
388        $(
389            #[cfg_attr(docsrs, doc(hidden))]
390            impl<$($name),+> Serialize for ($($name,)+)
391            where
392                $($name: Serialize,)+
393            {
394                tuple_impl_body!($len => ($($n)+));
395            }
396        )+
397    };
398}
399
400macro_rules! tuple_impl_body {
401    ($len:expr => ($($n:tt)+)) => {
402        #[inline]
403        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
404        where
405            S: Serializer,
406        {
407            let mut tuple = tri!(serializer.serialize_tuple($len));
408            $(
409                tri!(tuple.serialize_element(&self.$n));
410            )+
411            tuple.end()
412        }
413    };
414}
415
416#[cfg_attr(docsrs, doc(fake_variadic))]
417#[cfg_attr(
418    docsrs,
419    doc = "This trait is implemented for tuples up to 16 items long."
420)]
421impl<T> Serialize for (T,)
422where
423    T: Serialize,
424{
425    tuple_impl_body!(1 => (0));
426}
427
428tuple_impls! {
429    2 => (0 T0 1 T1)
430    3 => (0 T0 1 T1 2 T2)
431    4 => (0 T0 1 T1 2 T2 3 T3)
432    5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
433    6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
434    7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
435    8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
436    9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
437    10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
438    11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
439    12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
440    13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
441    14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
442    15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
443    16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
444}
445
446////////////////////////////////////////////////////////////////////////////////
447
448#[cfg(not(no_relaxed_trait_bounds))]
449macro_rules! map_impl {
450    (
451        $(#[$attr:meta])*
452        $ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)*>
453    ) => {
454        $(#[$attr])*
455        impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
456        where
457            K: Serialize,
458            V: Serialize,
459        {
460            #[inline]
461            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
462            where
463                S: Serializer,
464            {
465                serializer.collect_map(self)
466            }
467        }
468    }
469}
470
471#[cfg(no_relaxed_trait_bounds)]
472macro_rules! map_impl {
473    (
474        $(#[$attr:meta])*
475        $ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)*>
476    ) => {
477        $(#[$attr])*
478        impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
479        where
480            K: Serialize $(+ $kbound1 $(+ $kbound2)*)*,
481            V: Serialize,
482            $($typaram: $bound,)*
483        {
484            #[inline]
485            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
486            where
487                S: Serializer,
488            {
489                serializer.collect_map(self)
490            }
491        }
492    }
493}
494
495map_impl! {
496    #[cfg(any(feature = "std", feature = "alloc"))]
497    #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
498    BTreeMap<K: Ord, V>
499}
500
501map_impl! {
502    #[cfg(feature = "std")]
503    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
504    HashMap<K: Eq + Hash, V, H: BuildHasher>
505}
506
507////////////////////////////////////////////////////////////////////////////////
508
509macro_rules! deref_impl {
510    (
511        $(#[$attr:meta])*
512        <$($desc:tt)+
513    ) => {
514        $(#[$attr])*
515        impl <$($desc)+ {
516            #[inline]
517            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
518            where
519                S: Serializer,
520            {
521                (**self).serialize(serializer)
522            }
523        }
524    };
525}
526
527deref_impl! {
528    <'a, T> Serialize for &'a T where T: ?Sized + Serialize
529}
530
531deref_impl! {
532    <'a, T> Serialize for &'a mut T where T: ?Sized + Serialize
533}
534
535deref_impl! {
536    #[cfg(any(feature = "std", feature = "alloc"))]
537    #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
538    <T> Serialize for Box<T> where T: ?Sized + Serialize
539}
540
541deref_impl! {
542    /// This impl requires the [`"rc"`] Cargo feature of Serde.
543    ///
544    /// Serializing a data structure containing `Rc` will serialize a copy of
545    /// the contents of the `Rc` each time the `Rc` is referenced within the
546    /// data structure. Serialization will not attempt to deduplicate these
547    /// repeated data.
548    ///
549    /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
550    #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
551    #[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
552    <T> Serialize for Rc<T> where T: ?Sized + Serialize
553}
554
555deref_impl! {
556    /// This impl requires the [`"rc"`] Cargo feature of Serde.
557    ///
558    /// Serializing a data structure containing `Arc` will serialize a copy of
559    /// the contents of the `Arc` each time the `Arc` is referenced within the
560    /// data structure. Serialization will not attempt to deduplicate these
561    /// repeated data.
562    ///
563    /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
564    #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
565    #[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
566    <T> Serialize for Arc<T> where T: ?Sized + Serialize
567}
568
569deref_impl! {
570    #[cfg(any(feature = "std", feature = "alloc"))]
571    #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
572    <'a, T> Serialize for Cow<'a, T> where T: ?Sized + Serialize + ToOwned
573}
574
575////////////////////////////////////////////////////////////////////////////////
576
577/// This impl requires the [`"rc"`] Cargo feature of Serde.
578///
579/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
580#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
581#[cfg_attr(
582    docsrs,
583    doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc"))))
584)]
585impl<T> Serialize for RcWeak<T>
586where
587    T: ?Sized + Serialize,
588{
589    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
590    where
591        S: Serializer,
592    {
593        self.upgrade().serialize(serializer)
594    }
595}
596
597/// This impl requires the [`"rc"`] Cargo feature of Serde.
598///
599/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
600#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
601#[cfg_attr(
602    docsrs,
603    doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc"))))
604)]
605impl<T> Serialize for ArcWeak<T>
606where
607    T: ?Sized + Serialize,
608{
609    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
610    where
611        S: Serializer,
612    {
613        self.upgrade().serialize(serializer)
614    }
615}
616
617////////////////////////////////////////////////////////////////////////////////
618
619macro_rules! nonzero_integers {
620    ($($T:ident,)+) => {
621        $(
622            impl Serialize for num::$T {
623                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
624                where
625                    S: Serializer,
626                {
627                    self.get().serialize(serializer)
628                }
629            }
630        )+
631    }
632}
633
634nonzero_integers! {
635    NonZeroU8,
636    NonZeroU16,
637    NonZeroU32,
638    NonZeroU64,
639    NonZeroU128,
640    NonZeroUsize,
641}
642
643#[cfg(not(no_num_nonzero_signed))]
644nonzero_integers! {
645    NonZeroI8,
646    NonZeroI16,
647    NonZeroI32,
648    NonZeroI64,
649    NonZeroI128,
650    NonZeroIsize,
651}
652
653impl<T> Serialize for Cell<T>
654where
655    T: Serialize + Copy,
656{
657    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
658    where
659        S: Serializer,
660    {
661        self.get().serialize(serializer)
662    }
663}
664
665impl<T> Serialize for RefCell<T>
666where
667    T: ?Sized + Serialize,
668{
669    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
670    where
671        S: Serializer,
672    {
673        match self.try_borrow() {
674            Ok(value) => value.serialize(serializer),
675            Err(_) => Err(S::Error::custom("already mutably borrowed")),
676        }
677    }
678}
679
680#[cfg(feature = "std")]
681#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
682impl<T> Serialize for Mutex<T>
683where
684    T: ?Sized + Serialize,
685{
686    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
687    where
688        S: Serializer,
689    {
690        match self.lock() {
691            Ok(locked) => locked.serialize(serializer),
692            Err(_) => Err(S::Error::custom("lock poison error while serializing")),
693        }
694    }
695}
696
697#[cfg(feature = "std")]
698#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
699impl<T> Serialize for RwLock<T>
700where
701    T: ?Sized + Serialize,
702{
703    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
704    where
705        S: Serializer,
706    {
707        match self.read() {
708            Ok(locked) => locked.serialize(serializer),
709            Err(_) => Err(S::Error::custom("lock poison error while serializing")),
710        }
711    }
712}
713
714////////////////////////////////////////////////////////////////////////////////
715
716impl<T, E> Serialize for Result<T, E>
717where
718    T: Serialize,
719    E: Serialize,
720{
721    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
722    where
723        S: Serializer,
724    {
725        match *self {
726            Result::Ok(ref value) => serializer.serialize_newtype_variant("Result", 0, "Ok", value),
727            Result::Err(ref value) => {
728                serializer.serialize_newtype_variant("Result", 1, "Err", value)
729            }
730        }
731    }
732}
733
734////////////////////////////////////////////////////////////////////////////////
735
736impl Serialize for Duration {
737    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
738    where
739        S: Serializer,
740    {
741        use super::SerializeStruct;
742        let mut state = tri!(serializer.serialize_struct("Duration", 2));
743        tri!(state.serialize_field("secs", &self.as_secs()));
744        tri!(state.serialize_field("nanos", &self.subsec_nanos()));
745        state.end()
746    }
747}
748
749////////////////////////////////////////////////////////////////////////////////
750
751#[cfg(feature = "std")]
752#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
753impl Serialize for SystemTime {
754    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
755    where
756        S: Serializer,
757    {
758        use super::SerializeStruct;
759        let duration_since_epoch = match self.duration_since(UNIX_EPOCH) {
760            Ok(duration_since_epoch) => duration_since_epoch,
761            Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")),
762        };
763        let mut state = tri!(serializer.serialize_struct("SystemTime", 2));
764        tri!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
765        tri!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
766        state.end()
767    }
768}
769
770////////////////////////////////////////////////////////////////////////////////
771
772/// Serialize a value that implements `Display` as a string, when that string is
773/// statically known to never have more than a constant `MAX_LEN` bytes.
774///
775/// Panics if the `Display` impl tries to write more than `MAX_LEN` bytes.
776#[cfg(any(feature = "std", not(no_core_net)))]
777macro_rules! serialize_display_bounded_length {
778    ($value:expr, $max:expr, $serializer:expr) => {{
779        let mut buffer = [0u8; $max];
780        let mut writer = crate::format::Buf::new(&mut buffer);
781        write!(&mut writer, "{}", $value).unwrap();
782        $serializer.serialize_str(writer.as_str())
783    }};
784}
785
786#[cfg(any(feature = "std", not(no_core_net)))]
787impl Serialize for net::IpAddr {
788    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
789    where
790        S: Serializer,
791    {
792        if serializer.is_human_readable() {
793            match *self {
794                net::IpAddr::V4(ref a) => a.serialize(serializer),
795                net::IpAddr::V6(ref a) => a.serialize(serializer),
796            }
797        } else {
798            match *self {
799                net::IpAddr::V4(ref a) => {
800                    serializer.serialize_newtype_variant("IpAddr", 0, "V4", a)
801                }
802                net::IpAddr::V6(ref a) => {
803                    serializer.serialize_newtype_variant("IpAddr", 1, "V6", a)
804                }
805            }
806        }
807    }
808}
809
810#[cfg(any(feature = "std", not(no_core_net)))]
811const DEC_DIGITS_LUT: &[u8] = b"\
812      0001020304050607080910111213141516171819\
813      2021222324252627282930313233343536373839\
814      4041424344454647484950515253545556575859\
815      6061626364656667686970717273747576777879\
816      8081828384858687888990919293949596979899";
817
818#[cfg(any(feature = "std", not(no_core_net)))]
819#[inline]
820fn format_u8(mut n: u8, out: &mut [u8]) -> usize {
821    if n >= 100 {
822        let d1 = ((n % 100) << 1) as usize;
823        n /= 100;
824        out[0] = b'0' + n;
825        out[1] = DEC_DIGITS_LUT[d1];
826        out[2] = DEC_DIGITS_LUT[d1 + 1];
827        3
828    } else if n >= 10 {
829        let d1 = (n << 1) as usize;
830        out[0] = DEC_DIGITS_LUT[d1];
831        out[1] = DEC_DIGITS_LUT[d1 + 1];
832        2
833    } else {
834        out[0] = b'0' + n;
835        1
836    }
837}
838
839#[cfg(any(feature = "std", not(no_core_net)))]
840#[test]
841fn test_format_u8() {
842    let mut i = 0u8;
843
844    loop {
845        let mut buf = [0u8; 3];
846        let written = format_u8(i, &mut buf);
847        assert_eq!(i.to_string().as_bytes(), &buf[..written]);
848
849        match i.checked_add(1) {
850            Some(next) => i = next,
851            None => break,
852        }
853    }
854}
855
856#[cfg(any(feature = "std", not(no_core_net)))]
857impl Serialize for net::Ipv4Addr {
858    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
859    where
860        S: Serializer,
861    {
862        if serializer.is_human_readable() {
863            const MAX_LEN: usize = 15;
864            debug_assert_eq!(MAX_LEN, "101.102.103.104".len());
865            let mut buf = [b'.'; MAX_LEN];
866            let mut written = format_u8(self.octets()[0], &mut buf);
867            for oct in &self.octets()[1..] {
868                // Skip over delimiters that we initialized buf with
869                written += format_u8(*oct, &mut buf[written + 1..]) + 1;
870            }
871            // Safety: We've only written ASCII bytes to the buffer, so it is valid UTF-8
872            let buf = unsafe { str::from_utf8_unchecked(&buf[..written]) };
873            serializer.serialize_str(buf)
874        } else {
875            self.octets().serialize(serializer)
876        }
877    }
878}
879
880#[cfg(any(feature = "std", not(no_core_net)))]
881impl Serialize for net::Ipv6Addr {
882    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
883    where
884        S: Serializer,
885    {
886        if serializer.is_human_readable() {
887            const MAX_LEN: usize = 39;
888            debug_assert_eq!(MAX_LEN, "1001:1002:1003:1004:1005:1006:1007:1008".len());
889            serialize_display_bounded_length!(self, MAX_LEN, serializer)
890        } else {
891            self.octets().serialize(serializer)
892        }
893    }
894}
895
896#[cfg(any(feature = "std", not(no_core_net)))]
897impl Serialize for net::SocketAddr {
898    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
899    where
900        S: Serializer,
901    {
902        if serializer.is_human_readable() {
903            match *self {
904                net::SocketAddr::V4(ref addr) => addr.serialize(serializer),
905                net::SocketAddr::V6(ref addr) => addr.serialize(serializer),
906            }
907        } else {
908            match *self {
909                net::SocketAddr::V4(ref addr) => {
910                    serializer.serialize_newtype_variant("SocketAddr", 0, "V4", addr)
911                }
912                net::SocketAddr::V6(ref addr) => {
913                    serializer.serialize_newtype_variant("SocketAddr", 1, "V6", addr)
914                }
915            }
916        }
917    }
918}
919
920#[cfg(any(feature = "std", not(no_core_net)))]
921impl Serialize for net::SocketAddrV4 {
922    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
923    where
924        S: Serializer,
925    {
926        if serializer.is_human_readable() {
927            const MAX_LEN: usize = 21;
928            debug_assert_eq!(MAX_LEN, "101.102.103.104:65000".len());
929            serialize_display_bounded_length!(self, MAX_LEN, serializer)
930        } else {
931            (self.ip(), self.port()).serialize(serializer)
932        }
933    }
934}
935
936#[cfg(any(feature = "std", not(no_core_net)))]
937impl Serialize for net::SocketAddrV6 {
938    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
939    where
940        S: Serializer,
941    {
942        if serializer.is_human_readable() {
943            const MAX_LEN: usize = 58;
944            debug_assert_eq!(
945                MAX_LEN,
946                "[1001:1002:1003:1004:1005:1006:1007:1008%4294967295]:65000".len()
947            );
948            serialize_display_bounded_length!(self, MAX_LEN, serializer)
949        } else {
950            (self.ip(), self.port()).serialize(serializer)
951        }
952    }
953}
954
955////////////////////////////////////////////////////////////////////////////////
956
957#[cfg(feature = "std")]
958#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
959impl Serialize for Path {
960    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
961    where
962        S: Serializer,
963    {
964        match self.to_str() {
965            Some(s) => s.serialize(serializer),
966            None => Err(Error::custom("path contains invalid UTF-8 characters")),
967        }
968    }
969}
970
971#[cfg(feature = "std")]
972#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
973impl Serialize for PathBuf {
974    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
975    where
976        S: Serializer,
977    {
978        self.as_path().serialize(serializer)
979    }
980}
981
982#[cfg(all(feature = "std", any(unix, windows)))]
983#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))]
984impl Serialize for OsStr {
985    #[cfg(unix)]
986    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
987    where
988        S: Serializer,
989    {
990        use std::os::unix::ffi::OsStrExt;
991        serializer.serialize_newtype_variant("OsString", 0, "Unix", self.as_bytes())
992    }
993
994    #[cfg(windows)]
995    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
996    where
997        S: Serializer,
998    {
999        use std::os::windows::ffi::OsStrExt;
1000        let val = self.encode_wide().collect::<Vec<_>>();
1001        serializer.serialize_newtype_variant("OsString", 1, "Windows", &val)
1002    }
1003}
1004
1005#[cfg(all(feature = "std", any(unix, windows)))]
1006#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))]
1007impl Serialize for OsString {
1008    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1009    where
1010        S: Serializer,
1011    {
1012        self.as_os_str().serialize(serializer)
1013    }
1014}
1015
1016////////////////////////////////////////////////////////////////////////////////
1017
1018impl<T> Serialize for Wrapping<T>
1019where
1020    T: Serialize,
1021{
1022    #[inline]
1023    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1024    where
1025        S: Serializer,
1026    {
1027        self.0.serialize(serializer)
1028    }
1029}
1030
1031#[cfg(not(no_core_num_saturating))]
1032impl<T> Serialize for Saturating<T>
1033where
1034    T: Serialize,
1035{
1036    #[inline]
1037    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1038    where
1039        S: Serializer,
1040    {
1041        self.0.serialize(serializer)
1042    }
1043}
1044
1045impl<T> Serialize for Reverse<T>
1046where
1047    T: Serialize,
1048{
1049    #[inline]
1050    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1051    where
1052        S: Serializer,
1053    {
1054        self.0.serialize(serializer)
1055    }
1056}
1057
1058////////////////////////////////////////////////////////////////////////////////
1059
1060#[cfg(all(feature = "std", not(no_std_atomic)))]
1061macro_rules! atomic_impl {
1062    ($($ty:ident $size:expr)*) => {
1063        $(
1064            #[cfg(any(no_target_has_atomic, target_has_atomic = $size))]
1065            #[cfg_attr(docsrs, doc(cfg(all(feature = "std", target_has_atomic = $size))))]
1066            impl Serialize for $ty {
1067                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1068                where
1069                    S: Serializer,
1070                {
1071                    // Matches the atomic ordering used in libcore for the Debug impl
1072                    self.load(Ordering::Relaxed).serialize(serializer)
1073                }
1074            }
1075        )*
1076    }
1077}
1078
1079#[cfg(all(feature = "std", not(no_std_atomic)))]
1080atomic_impl! {
1081    AtomicBool "8"
1082    AtomicI8 "8"
1083    AtomicI16 "16"
1084    AtomicI32 "32"
1085    AtomicIsize "ptr"
1086    AtomicU8 "8"
1087    AtomicU16 "16"
1088    AtomicU32 "32"
1089    AtomicUsize "ptr"
1090}
1091
1092#[cfg(all(feature = "std", not(no_std_atomic64)))]
1093atomic_impl! {
1094    AtomicI64 "64"
1095    AtomicU64 "64"
1096}