1 | use crate::lib::*; |
2 | |
3 | use crate::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!(i128, serialize_i128); |
28 | primitive_impl!(usize, serialize_u64 as u64); |
29 | primitive_impl!(u8, serialize_u8); |
30 | primitive_impl!(u16, serialize_u16); |
31 | primitive_impl!(u32, serialize_u32); |
32 | primitive_impl!(u64, serialize_u64); |
33 | primitive_impl!(u128, serialize_u128); |
34 | primitive_impl!(f32, serialize_f32); |
35 | primitive_impl!(f64, serialize_f64); |
36 | primitive_impl!(char, serialize_char); |
37 | |
38 | //////////////////////////////////////////////////////////////////////////////// |
39 | |
40 | impl 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" ))))] |
52 | impl 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 | |
62 | impl<'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" )))] |
75 | impl 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" ))))] |
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: &T) => 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(name:"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 | tri!(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 = 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 | |
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 (not(no_relaxed_trait_bounds))] |
186 | macro_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)] |
208 | macro_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 | |
230 | seq_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 | |
236 | seq_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 | |
242 | seq_impl! { |
243 | #[cfg (feature = "std" )] |
244 | #[cfg_attr (doc_cfg, doc(cfg(feature = "std" )))] |
245 | HashSet<T: Eq + Hash, H: BuildHasher> |
246 | } |
247 | |
248 | seq_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 | |
254 | seq_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 | |
260 | seq_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 | |
268 | impl<Idx> Serialize for Range<Idx> |
269 | where |
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: ::SerializeStruct = 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 | |
286 | impl<Idx> Serialize for RangeFrom<Idx> |
287 | where |
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: ::SerializeStruct = tri!(serializer.serialize_struct("RangeFrom" , 1)); |
296 | tri!(state.serialize_field("start" , &self.start)); |
297 | state.end() |
298 | } |
299 | } |
300 | |
301 | //////////////////////////////////////////////////////////////////////////////// |
302 | |
303 | impl<Idx> Serialize for RangeInclusive<Idx> |
304 | where |
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: ::SerializeStruct = 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 | |
321 | impl<Idx> Serialize for RangeTo<Idx> |
322 | where |
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: ::SerializeStruct = tri!(serializer.serialize_struct("RangeTo" , 1)); |
331 | tri!(state.serialize_field("end" , &self.end)); |
332 | state.end() |
333 | } |
334 | } |
335 | |
336 | //////////////////////////////////////////////////////////////////////////////// |
337 | |
338 | impl<T> Serialize for Bound<T> |
339 | where |
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(name:"Bound" , variant_index:0, variant:"Unbounded" ), |
348 | Bound::Included(ref value: &T) => { |
349 | serializer.serialize_newtype_variant(name:"Bound" , variant_index:1, variant:"Included" , value) |
350 | } |
351 | Bound::Excluded(ref value: &T) => { |
352 | serializer.serialize_newtype_variant(name:"Bound" , variant_index:2, variant:"Excluded" , value) |
353 | } |
354 | } |
355 | } |
356 | } |
357 | |
358 | //////////////////////////////////////////////////////////////////////////////// |
359 | |
360 | impl 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" )))] |
372 | impl 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 | |
383 | macro_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 | |
406 | tuple_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))] |
428 | macro_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)] |
451 | macro_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 | |
474 | map_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 | |
480 | map_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 | |
488 | macro_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 | |
506 | deref_impl! { |
507 | <'a, T: ?Sized> Serialize for &'a T where T: Serialize |
508 | } |
509 | |
510 | deref_impl! { |
511 | <'a, T: ?Sized> Serialize for &'a mut T where T: Serialize |
512 | } |
513 | |
514 | deref_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 | |
520 | deref_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 | |
534 | deref_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 | |
548 | deref_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 | )] |
564 | impl<T: ?Sized> Serialize for RcWeak<T> |
565 | where |
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 | )] |
584 | impl<T: ?Sized> Serialize for ArcWeak<T> |
585 | where |
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 | |
598 | macro_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 | |
613 | nonzero_integers! { |
614 | NonZeroU8, |
615 | NonZeroU16, |
616 | NonZeroU32, |
617 | NonZeroU64, |
618 | NonZeroU128, |
619 | NonZeroUsize, |
620 | } |
621 | |
622 | #[cfg (not(no_num_nonzero_signed))] |
623 | nonzero_integers! { |
624 | NonZeroI8, |
625 | NonZeroI16, |
626 | NonZeroI32, |
627 | NonZeroI64, |
628 | NonZeroI128, |
629 | NonZeroIsize, |
630 | } |
631 | |
632 | impl<T> Serialize for Cell<T> |
633 | where |
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 | |
644 | impl<T: ?Sized> Serialize for RefCell<T> |
645 | where |
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: Ref<'_, T>) => value.serialize(serializer), |
654 | Err(_) => Err(S::Error::custom(msg:"already mutably borrowed" )), |
655 | } |
656 | } |
657 | } |
658 | |
659 | #[cfg (feature = "std" )] |
660 | #[cfg_attr (doc_cfg, doc(cfg(feature = "std" )))] |
661 | impl<T: ?Sized> Serialize for Mutex<T> |
662 | where |
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: MutexGuard<'_, T>) => locked.serialize(serializer), |
671 | Err(_) => Err(S::Error::custom(msg:"lock poison error while serializing" )), |
672 | } |
673 | } |
674 | } |
675 | |
676 | #[cfg (feature = "std" )] |
677 | #[cfg_attr (doc_cfg, doc(cfg(feature = "std" )))] |
678 | impl<T: ?Sized> Serialize for RwLock<T> |
679 | where |
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: RwLockReadGuard<'_, T>) => locked.serialize(serializer), |
688 | Err(_) => Err(S::Error::custom(msg:"lock poison error while serializing" )), |
689 | } |
690 | } |
691 | } |
692 | |
693 | //////////////////////////////////////////////////////////////////////////////// |
694 | |
695 | impl<T, E> Serialize for Result<T, E> |
696 | where |
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: &T) => serializer.serialize_newtype_variant(name:"Result" , variant_index:0, variant:"Ok" , value), |
706 | Result::Err(ref value: &E) => { |
707 | serializer.serialize_newtype_variant(name:"Result" , variant_index:1, variant:"Err" , value) |
708 | } |
709 | } |
710 | } |
711 | } |
712 | |
713 | //////////////////////////////////////////////////////////////////////////////// |
714 | |
715 | impl 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: ::SerializeStruct = 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" )))] |
732 | impl 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: Duration = match self.duration_since(UNIX_EPOCH) { |
739 | Ok(duration_since_epoch: Duration) => duration_since_epoch, |
740 | Err(_) => return Err(S::Error::custom(msg:"SystemTime must be later than UNIX_EPOCH" )), |
741 | }; |
742 | let mut state: ::SerializeStruct = 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" )] |
756 | macro_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" )))] |
777 | impl 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: &Ipv4Addr) => a.serialize(serializer), |
785 | net::IpAddr::V6(ref a: &Ipv6Addr) => a.serialize(serializer), |
786 | } |
787 | } else { |
788 | match *self { |
789 | net::IpAddr::V4(ref a: &Ipv4Addr) => { |
790 | serializer.serialize_newtype_variant(name:"IpAddr" , variant_index:0, variant:"V4" , value:a) |
791 | } |
792 | net::IpAddr::V6(ref a: &Ipv6Addr) => { |
793 | serializer.serialize_newtype_variant(name:"IpAddr" , variant_index:1, variant:"V6" , value:a) |
794 | } |
795 | } |
796 | } |
797 | } |
798 | } |
799 | |
800 | #[cfg (feature = "std" )] |
801 | const DEC_DIGITS_LUT: &[u8] = b"\ |
802 | 0001020304050607080910111213141516171819\ |
803 | 2021222324252627282930313233343536373839\ |
804 | 4041424344454647484950515253545556575859\ |
805 | 6061626364656667686970717273747576777879\ |
806 | 8081828384858687888990919293949596979899" ; |
807 | |
808 | #[cfg (feature = "std" )] |
809 | #[inline ] |
810 | fn format_u8(mut n: u8, out: &mut [u8]) -> usize { |
811 | if n >= 100 { |
812 | let d1: usize = ((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: usize = (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 ] |
831 | fn test_format_u8() { |
832 | let mut i: u8 = 0u8; |
833 | |
834 | loop { |
835 | let mut buf: [u8; 3] = [0u8; 3]; |
836 | let written: usize = format_u8(n:i, &mut buf); |
837 | assert_eq!(i.to_string().as_bytes(), &buf[..written]); |
838 | |
839 | match i.checked_add(1) { |
840 | Some(next: u8) => i = next, |
841 | None => break, |
842 | } |
843 | } |
844 | } |
845 | |
846 | #[cfg (feature = "std" )] |
847 | #[cfg_attr (doc_cfg, doc(cfg(feature = "std" )))] |
848 | impl 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: [u8; 15] = [b'.' ; MAX_LEN]; |
857 | let mut written: usize = format_u8(self.octets()[0], &mut buf); |
858 | for oct: &u8 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: &str = 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" )))] |
873 | impl 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" )))] |
890 | impl 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: &SocketAddrV4) => addr.serialize(serializer), |
898 | net::SocketAddr::V6(ref addr: &SocketAddrV6) => addr.serialize(serializer), |
899 | } |
900 | } else { |
901 | match *self { |
902 | net::SocketAddr::V4(ref addr: &SocketAddrV4) => { |
903 | serializer.serialize_newtype_variant(name:"SocketAddr" , variant_index:0, variant:"V4" , value:addr) |
904 | } |
905 | net::SocketAddr::V6(ref addr: &SocketAddrV6) => { |
906 | serializer.serialize_newtype_variant(name:"SocketAddr" , variant_index:1, variant:"V6" , value:addr) |
907 | } |
908 | } |
909 | } |
910 | } |
911 | } |
912 | |
913 | #[cfg (feature = "std" )] |
914 | #[cfg_attr (doc_cfg, doc(cfg(feature = "std" )))] |
915 | impl 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" )))] |
932 | impl 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" )))] |
954 | impl 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: &str) => s.serialize(serializer), |
961 | None => Err(Error::custom(msg:"path contains invalid UTF-8 characters" )), |
962 | } |
963 | } |
964 | } |
965 | |
966 | #[cfg (feature = "std" )] |
967 | #[cfg_attr (doc_cfg, doc(cfg(feature = "std" )))] |
968 | impl 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)))))] |
979 | impl 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(name:"OsString" , variant_index:0, variant:"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)))))] |
1002 | impl 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 | |
1013 | impl<T> Serialize for Wrapping<T> |
1014 | where |
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 | |
1026 | impl<T> Serialize for Reverse<T> |
1027 | where |
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)))] |
1042 | macro_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)))] |
1061 | atomic_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)))] |
1074 | atomic_impl! { |
1075 | AtomicI64 "64" |
1076 | AtomicU64 "64" |
1077 | } |
1078 | |