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