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