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(feature = "std")]
777macro_rules! serialize_display_bounded_length {
778    ($value:expr, $max:expr, $serializer:expr) => {{
779        let mut buffer = [0u8; $max];
780        let remaining_len = {
781            let mut remaining = &mut buffer[..];
782            write!(remaining, "{}", $value).unwrap();
783            remaining.len()
784        };
785        let written_len = buffer.len() - remaining_len;
786        let written = &buffer[..written_len];
787
788        // write! only provides fmt::Formatter to Display implementations, which
789        // has methods write_str and write_char but no method to write arbitrary
790        // bytes. Therefore `written` must be valid UTF-8.
791        let written_str = str::from_utf8(written).expect("must be valid UTF-8");
792        $serializer.serialize_str(written_str)
793    }};
794}
795
796#[cfg(feature = "std")]
797#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
798impl Serialize for net::IpAddr {
799    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
800    where
801        S: Serializer,
802    {
803        if serializer.is_human_readable() {
804            match *self {
805                net::IpAddr::V4(ref a) => a.serialize(serializer),
806                net::IpAddr::V6(ref a) => a.serialize(serializer),
807            }
808        } else {
809            match *self {
810                net::IpAddr::V4(ref a) => {
811                    serializer.serialize_newtype_variant("IpAddr", 0, "V4", a)
812                }
813                net::IpAddr::V6(ref a) => {
814                    serializer.serialize_newtype_variant("IpAddr", 1, "V6", a)
815                }
816            }
817        }
818    }
819}
820
821#[cfg(feature = "std")]
822const DEC_DIGITS_LUT: &[u8] = b"\
823      0001020304050607080910111213141516171819\
824      2021222324252627282930313233343536373839\
825      4041424344454647484950515253545556575859\
826      6061626364656667686970717273747576777879\
827      8081828384858687888990919293949596979899";
828
829#[cfg(feature = "std")]
830#[inline]
831fn format_u8(mut n: u8, out: &mut [u8]) -> usize {
832    if n >= 100 {
833        let d1 = ((n % 100) << 1) as usize;
834        n /= 100;
835        out[0] = b'0' + n;
836        out[1] = DEC_DIGITS_LUT[d1];
837        out[2] = DEC_DIGITS_LUT[d1 + 1];
838        3
839    } else if n >= 10 {
840        let d1 = (n << 1) as usize;
841        out[0] = DEC_DIGITS_LUT[d1];
842        out[1] = DEC_DIGITS_LUT[d1 + 1];
843        2
844    } else {
845        out[0] = b'0' + n;
846        1
847    }
848}
849
850#[cfg(feature = "std")]
851#[test]
852fn test_format_u8() {
853    let mut i = 0u8;
854
855    loop {
856        let mut buf = [0u8; 3];
857        let written = format_u8(i, &mut buf);
858        assert_eq!(i.to_string().as_bytes(), &buf[..written]);
859
860        match i.checked_add(1) {
861            Some(next) => i = next,
862            None => break,
863        }
864    }
865}
866
867#[cfg(feature = "std")]
868#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
869impl Serialize for net::Ipv4Addr {
870    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
871    where
872        S: Serializer,
873    {
874        if serializer.is_human_readable() {
875            const MAX_LEN: usize = 15;
876            debug_assert_eq!(MAX_LEN, "101.102.103.104".len());
877            let mut buf = [b'.'; MAX_LEN];
878            let mut written = format_u8(self.octets()[0], &mut buf);
879            for oct in &self.octets()[1..] {
880                // Skip over delimiters that we initialized buf with
881                written += format_u8(*oct, &mut buf[written + 1..]) + 1;
882            }
883            // Safety: We've only written ASCII bytes to the buffer, so it is valid UTF-8
884            let buf = unsafe { str::from_utf8_unchecked(&buf[..written]) };
885            serializer.serialize_str(buf)
886        } else {
887            self.octets().serialize(serializer)
888        }
889    }
890}
891
892#[cfg(feature = "std")]
893#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
894impl Serialize for net::Ipv6Addr {
895    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
896    where
897        S: Serializer,
898    {
899        if serializer.is_human_readable() {
900            const MAX_LEN: usize = 39;
901            debug_assert_eq!(MAX_LEN, "1001:1002:1003:1004:1005:1006:1007:1008".len());
902            serialize_display_bounded_length!(self, MAX_LEN, serializer)
903        } else {
904            self.octets().serialize(serializer)
905        }
906    }
907}
908
909#[cfg(feature = "std")]
910#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
911impl Serialize for net::SocketAddr {
912    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
913    where
914        S: Serializer,
915    {
916        if serializer.is_human_readable() {
917            match *self {
918                net::SocketAddr::V4(ref addr) => addr.serialize(serializer),
919                net::SocketAddr::V6(ref addr) => addr.serialize(serializer),
920            }
921        } else {
922            match *self {
923                net::SocketAddr::V4(ref addr) => {
924                    serializer.serialize_newtype_variant("SocketAddr", 0, "V4", addr)
925                }
926                net::SocketAddr::V6(ref addr) => {
927                    serializer.serialize_newtype_variant("SocketAddr", 1, "V6", addr)
928                }
929            }
930        }
931    }
932}
933
934#[cfg(feature = "std")]
935#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
936impl Serialize for net::SocketAddrV4 {
937    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
938    where
939        S: Serializer,
940    {
941        if serializer.is_human_readable() {
942            const MAX_LEN: usize = 21;
943            debug_assert_eq!(MAX_LEN, "101.102.103.104:65000".len());
944            serialize_display_bounded_length!(self, MAX_LEN, serializer)
945        } else {
946            (self.ip(), self.port()).serialize(serializer)
947        }
948    }
949}
950
951#[cfg(feature = "std")]
952#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
953impl Serialize for net::SocketAddrV6 {
954    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
955    where
956        S: Serializer,
957    {
958        if serializer.is_human_readable() {
959            const MAX_LEN: usize = 58;
960            debug_assert_eq!(
961                MAX_LEN,
962                "[1001:1002:1003:1004:1005:1006:1007:1008%4294967295]:65000".len()
963            );
964            serialize_display_bounded_length!(self, MAX_LEN, serializer)
965        } else {
966            (self.ip(), self.port()).serialize(serializer)
967        }
968    }
969}
970
971////////////////////////////////////////////////////////////////////////////////
972
973#[cfg(feature = "std")]
974#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
975impl Serialize for Path {
976    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
977    where
978        S: Serializer,
979    {
980        match self.to_str() {
981            Some(s) => s.serialize(serializer),
982            None => Err(Error::custom("path contains invalid UTF-8 characters")),
983        }
984    }
985}
986
987#[cfg(feature = "std")]
988#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
989impl Serialize for PathBuf {
990    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
991    where
992        S: Serializer,
993    {
994        self.as_path().serialize(serializer)
995    }
996}
997
998#[cfg(all(feature = "std", any(unix, windows)))]
999#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))]
1000impl Serialize for OsStr {
1001    #[cfg(unix)]
1002    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1003    where
1004        S: Serializer,
1005    {
1006        use std::os::unix::ffi::OsStrExt;
1007        serializer.serialize_newtype_variant("OsString", 0, "Unix", self.as_bytes())
1008    }
1009
1010    #[cfg(windows)]
1011    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1012    where
1013        S: Serializer,
1014    {
1015        use std::os::windows::ffi::OsStrExt;
1016        let val = self.encode_wide().collect::<Vec<_>>();
1017        serializer.serialize_newtype_variant("OsString", 1, "Windows", &val)
1018    }
1019}
1020
1021#[cfg(all(feature = "std", any(unix, windows)))]
1022#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))]
1023impl Serialize for OsString {
1024    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1025    where
1026        S: Serializer,
1027    {
1028        self.as_os_str().serialize(serializer)
1029    }
1030}
1031
1032////////////////////////////////////////////////////////////////////////////////
1033
1034impl<T> Serialize for Wrapping<T>
1035where
1036    T: Serialize,
1037{
1038    #[inline]
1039    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1040    where
1041        S: Serializer,
1042    {
1043        self.0.serialize(serializer)
1044    }
1045}
1046
1047#[cfg(not(no_core_num_saturating))]
1048impl<T> Serialize for Saturating<T>
1049where
1050    T: Serialize,
1051{
1052    #[inline]
1053    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1054    where
1055        S: Serializer,
1056    {
1057        self.0.serialize(serializer)
1058    }
1059}
1060
1061impl<T> Serialize for Reverse<T>
1062where
1063    T: Serialize,
1064{
1065    #[inline]
1066    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1067    where
1068        S: Serializer,
1069    {
1070        self.0.serialize(serializer)
1071    }
1072}
1073
1074////////////////////////////////////////////////////////////////////////////////
1075
1076#[cfg(all(feature = "std", not(no_std_atomic)))]
1077macro_rules! atomic_impl {
1078    ($($ty:ident $size:expr)*) => {
1079        $(
1080            #[cfg(any(no_target_has_atomic, target_has_atomic = $size))]
1081            #[cfg_attr(docsrs, doc(cfg(all(feature = "std", target_has_atomic = $size))))]
1082            impl Serialize for $ty {
1083                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1084                where
1085                    S: Serializer,
1086                {
1087                    // Matches the atomic ordering used in libcore for the Debug impl
1088                    self.load(Ordering::Relaxed).serialize(serializer)
1089                }
1090            }
1091        )*
1092    }
1093}
1094
1095#[cfg(all(feature = "std", not(no_std_atomic)))]
1096atomic_impl! {
1097    AtomicBool "8"
1098    AtomicI8 "8"
1099    AtomicI16 "16"
1100    AtomicI32 "32"
1101    AtomicIsize "ptr"
1102    AtomicU8 "8"
1103    AtomicU16 "16"
1104    AtomicU32 "32"
1105    AtomicUsize "ptr"
1106}
1107
1108#[cfg(all(feature = "std", not(no_std_atomic64)))]
1109atomic_impl! {
1110    AtomicI64 "64"
1111    AtomicU64 "64"
1112}