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}
1078