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