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