1use core::ffi::CStr;
2use core::fmt;
3#[cfg(feature = "std")]
4use core::hash::{BuildHasher, Hash};
5
6use rust_alloc::borrow::{Cow, ToOwned};
7use rust_alloc::boxed::Box;
8use rust_alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, VecDeque};
9use rust_alloc::ffi::CString;
10use rust_alloc::rc::Rc;
11use rust_alloc::string::String;
12use rust_alloc::sync::Arc;
13use rust_alloc::vec::Vec;
14
15#[cfg(feature = "std")]
16use std::collections::{HashMap, HashSet};
17#[cfg(all(feature = "std", any(unix, windows)))]
18use std::ffi::{OsStr, OsString};
19#[cfg(all(feature = "std", any(unix, windows)))]
20use std::path::{Path, PathBuf};
21
22use crate::de::{
23 Decode, DecodeBytes, DecodeTrace, Decoder, EntryDecoder, MapDecoder, SequenceDecoder,
24 UnsizedVisitor,
25};
26use crate::en::{
27 Encode, EncodeBytes, EncodePacked, EncodeTrace, Encoder, EntryEncoder, MapEncoder,
28 SequenceEncoder,
29};
30use crate::hint::{MapHint, SequenceHint};
31use crate::internal::size_hint;
32use crate::Context;
33
34#[cfg(all(feature = "std", any(unix, windows)))]
35use super::PlatformTag;
36
37impl<M> Encode<M> for String {
38 #[inline]
39 fn encode<E>(&self, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
40 where
41 E: Encoder<Mode = M>,
42 {
43 self.as_str().encode(cx, encoder)
44 }
45}
46
47impl<'de, M> Decode<'de, M> for String {
48 #[inline]
49 fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
50 where
51 D: Decoder<'de, Mode = M>,
52 {
53 struct Visitor;
54
55 impl<'de, C> UnsizedVisitor<'de, C, str> for Visitor
56 where
57 C: ?Sized + Context,
58 {
59 type Ok = String;
60
61 #[inline]
62 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 write!(f, "string")
64 }
65
66 #[inline]
67 fn visit_owned(self, _: &C, value: String) -> Result<Self::Ok, C::Error> {
68 Ok(value)
69 }
70
71 #[inline]
72 fn visit_borrowed(self, cx: &C, string: &'de str) -> Result<Self::Ok, C::Error> {
73 self.visit_ref(cx, string)
74 }
75
76 #[inline]
77 fn visit_ref(self, _: &C, string: &str) -> Result<Self::Ok, C::Error> {
78 Ok(string.to_owned())
79 }
80 }
81
82 decoder.decode_string(Visitor)
83 }
84}
85
86impl<'de, M> Decode<'de, M> for Box<str> {
87 #[inline]
88 fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
89 where
90 D: Decoder<'de, Mode = M>,
91 {
92 Ok(decoder.decode::<String>()?.into())
93 }
94}
95
96impl<'de, M, T> Decode<'de, M> for Box<[T]>
97where
98 T: Decode<'de, M>,
99{
100 #[inline]
101 fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
102 where
103 D: Decoder<'de, Mode = M>,
104 {
105 Ok(decoder.decode::<Vec<T>>()?.into())
106 }
107}
108
109macro_rules! cow {
110 (
111 $encode:ident :: $encode_fn:ident,
112 $decode:ident :: $decode_fn:ident,
113 $ty:ty, $source:ty,
114 $decode_method:ident, $cx:pat,
115 |$owned:ident| $owned_expr:expr,
116 |$borrowed:ident| $borrowed_expr:expr,
117 |$reference:ident| $reference_expr:expr $(,)?
118 ) => {
119 impl<M> $encode<M> for Cow<'_, $ty> {
120 #[inline]
121 fn $encode_fn<E>(&self, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
122 where
123 E: Encoder<Mode = M>,
124 {
125 self.as_ref().$encode_fn(cx, encoder)
126 }
127 }
128
129 impl<'de, M> $decode<'de, M> for Cow<'de, $ty> {
130 #[inline]
131 fn $decode_fn<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
132 where
133 D: Decoder<'de, Mode = M>,
134 {
135 struct Visitor;
136
137 impl<'de, C> UnsizedVisitor<'de, C, $source> for Visitor
138 where
139 C: ?Sized + Context,
140 {
141 type Ok = Cow<'de, $ty>;
142
143 #[inline]
144 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145 write!(f, "a string")
146 }
147
148 #[inline]
149 fn visit_owned(
150 self,
151 $cx: &C,
152 $owned: <$source as ToOwned>::Owned,
153 ) -> Result<Self::Ok, C::Error> {
154 Ok($owned_expr)
155 }
156
157 #[inline]
158 fn visit_borrowed(
159 self,
160 $cx: &C,
161 $borrowed: &'de $source,
162 ) -> Result<Self::Ok, C::Error> {
163 Ok($borrowed_expr)
164 }
165
166 #[inline]
167 fn visit_ref(
168 self,
169 $cx: &C,
170 $reference: &$source,
171 ) -> Result<Self::Ok, C::Error> {
172 Ok($reference_expr)
173 }
174 }
175
176 decoder.$decode_method(Visitor)
177 }
178 }
179 };
180}
181
182cow! {
183 Encode::encode,
184 Decode::decode,
185 str, str, decode_string, _,
186 |owned| Cow::Owned(owned),
187 |borrowed| Cow::Borrowed(borrowed),
188 |reference| Cow::Owned(reference.to_owned())
189}
190
191cow! {
192 Encode::encode,
193 Decode::decode,
194 CStr, [u8], decode_bytes, cx,
195 |owned| Cow::Owned(CString::from_vec_with_nul(owned).map_err(cx.map())?),
196 |borrowed| Cow::Borrowed(CStr::from_bytes_with_nul(borrowed).map_err(cx.map())?),
197 |reference| Cow::Owned(CStr::from_bytes_with_nul(reference).map_err(cx.map())?.to_owned())
198}
199
200cow! {
201 EncodeBytes::encode_bytes,
202 DecodeBytes::decode_bytes,
203 [u8], [u8], decode_bytes, _,
204 |owned| Cow::Owned(owned),
205 |borrowed| Cow::Borrowed(borrowed),
206 |reference| Cow::Owned(reference.to_owned())
207}
208
209macro_rules! sequence {
210 (
211 $(#[$($meta:meta)*])*
212 $cx:ident,
213 $ty:ident <T $(: $trait0:ident $(+ $trait:ident)*)? $(, $extra:ident: $extra_bound0:ident $(+ $extra_bound:ident)*)*>,
214 $insert:ident,
215 $access:ident,
216 $factory:expr
217 ) => {
218 $(#[$($meta)*])*
219 impl<M, T $(, $extra)*> Encode<M> for $ty<T $(, $extra)*>
220 where
221 T: Encode<M>,
222 $($extra: $extra_bound0 $(+ $extra_bound)*),*
223 {
224 #[inline]
225 fn encode<E>(&self, $cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
226 where
227 E: Encoder<Mode = M>,
228 {
229 let hint = SequenceHint::with_size(self.len());
230
231 encoder.encode_sequence_fn(&hint, |seq| {
232 let mut index = 0;
233
234 for value in self {
235 $cx.enter_sequence_index(index);
236 seq.push(value)?;
237 $cx.leave_sequence_index();
238 index = index.wrapping_add(1);
239 }
240
241 Ok(())
242 })
243 }
244 }
245
246 $(#[$($meta)*])*
247 impl<'de, M, T $(, $extra)*> Decode<'de, M> for $ty<T $(, $extra)*>
248 where
249 T: Decode<'de, M> $(+ $trait0 $(+ $trait)*)*,
250 $($extra: $extra_bound0 $(+ $extra_bound)*),*
251 {
252 #[inline]
253 fn decode<D>($cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
254 where
255 D: Decoder<'de, Mode = M>,
256 {
257 decoder.decode_sequence(|$access| {
258 let mut out = $factory;
259
260 let mut index = 0;
261
262 while let Some(value) = $access.try_decode_next()? {
263 $cx.enter_sequence_index(index);
264 out.$insert(T::decode($cx, value)?);
265 $cx.leave_sequence_index();
266 index = index.wrapping_add(1);
267 }
268
269 Ok(out)
270 })
271 }
272 }
273
274 $(#[$($meta)*])*
275 impl<M, T $(, $extra)*> EncodePacked<M> for $ty<T $(, $extra)*>
276 where
277 T: Encode<M>,
278 $($extra: $extra_bound0 $(+ $extra_bound)*),*
279 {
280 #[inline]
281 fn encode_packed<E>(&self, $cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
282 where
283 E: Encoder<Mode = M>,
284 {
285 encoder.encode_pack_fn(|pack| {
286 let mut index = 0;
287
288 for value in self {
289 $cx.enter_sequence_index(index);
290 pack.push(value)?;
291 $cx.leave_sequence_index();
292 index = index.wrapping_add(1);
293 }
294
295 Ok(())
296 })
297 }
298 }
299 }
300}
301
302sequence!(
303 cx,
304 Vec<T>,
305 push,
306 seq,
307 Vec::with_capacity(size_hint::cautious(seq.size_hint()))
308);
309sequence!(
310 cx,
311 VecDeque<T>,
312 push_back,
313 seq,
314 VecDeque::with_capacity(size_hint::cautious(seq.size_hint()))
315);
316sequence!(cx, BTreeSet<T: Ord>, insert, seq, BTreeSet::new());
317sequence!(
318 #[cfg(feature = "std")]
319 #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
320 cx,
321 HashSet<T: Eq + Hash, S: BuildHasher + Default>,
322 insert,
323 seq,
324 HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default())
325);
326sequence!(
327 cx,
328 BinaryHeap<T: Ord>,
329 push,
330 seq,
331 BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint()))
332);
333
334macro_rules! map {
335 (
336 $(#[$($meta:meta)*])*
337 $cx:ident,
338 $ty:ident<K $(: $key_bound0:ident $(+ $key_bound:ident)*)?, V $(, $extra:ident: $extra_bound0:ident $(+ $extra_bound:ident)*)*>,
339 $access:ident,
340 $with_capacity:expr
341 ) => {
342 $(#[$($meta)*])*
343 impl<'de, M, K, V $(, $extra)*> Encode<M> for $ty<K, V $(, $extra)*>
344 where
345 K: Encode<M>,
346 V: Encode<M>,
347 $($extra: $extra_bound0 $(+ $extra_bound)*),*
348 {
349 #[inline]
350 fn encode<E>(&self, $cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
351 where
352 E: Encoder<Mode = M>,
353 {
354 let hint = MapHint::with_size(self.len());
355
356 encoder.encode_map_fn(&hint, |map| {
357 for (k, v) in self {
358 map.insert_entry(k, v)?;
359 }
360
361 Ok(())
362 })
363 }
364 }
365
366 $(#[$($meta)*])*
367 impl<'de, M, K, V $(, $extra)*> EncodeTrace<M> for $ty<K, V $(, $extra)*>
368 where
369 K: fmt::Display + Encode<M>,
370 V: Encode<M>,
371 $($extra: $extra_bound0 $(+ $extra_bound)*),*
372 {
373 #[inline]
374 fn trace_encode<E>(&self, $cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
375 where
376 E: Encoder<Mode = M>,
377 {
378 let hint = MapHint::with_size(self.len());
379
380 encoder.encode_map_fn(&hint, |map| {
381 for (k, v) in self {
382 $cx.enter_map_key(k);
383 map.encode_entry_fn(|entry| {
384 entry.encode_key()?.encode(k)?;
385 entry.encode_value()?.encode(v)?;
386 Ok(())
387 })?;
388 $cx.leave_map_key();
389 }
390
391 Ok(())
392 })
393 }
394 }
395
396 $(#[$($meta)*])*
397 impl<'de, K, V, M $(, $extra)*> Decode<'de, M> for $ty<K, V $(, $extra)*>
398 where
399 K: Decode<'de, M> $(+ $key_bound0 $(+ $key_bound)*)*,
400 V: Decode<'de, M>,
401 $($extra: $extra_bound0 $(+ $extra_bound)*),*
402 {
403 #[inline]
404 fn decode<D>($cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
405 where
406 D: Decoder<'de, Mode = M>,
407 {
408 decoder.decode_map(|$access| {
409 let mut out = $with_capacity;
410
411 while let Some((key, value)) = $access.entry()? {
412 out.insert(key, value);
413 }
414
415 Ok(out)
416 })
417 }
418 }
419
420 $(#[$($meta)*])*
421 impl<'de, K, V, M $(, $extra)*> DecodeTrace<'de, M> for $ty<K, V $(, $extra)*>
422 where
423 K: fmt::Display + Decode<'de, M> $(+ $key_bound0 $(+ $key_bound)*)*,
424 V: Decode<'de, M>,
425 $($extra: $extra_bound0 $(+ $extra_bound)*),*
426 {
427 #[inline]
428 fn trace_decode<D>($cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
429 where
430 D: Decoder<'de, Mode = M>,
431 {
432 decoder.decode_map(|$access| {
433 let mut out = $with_capacity;
434
435 while let Some(mut entry) = $access.decode_entry()? {
436 let key = entry.decode_key()?.decode()?;
437 $cx.enter_map_key(&key);
438 let value = entry.decode_value()?.decode()?;
439 out.insert(key, value);
440 $cx.leave_map_key();
441 }
442
443 Ok(out)
444 })
445 }
446 }
447 }
448}
449
450map!(_cx, BTreeMap<K: Ord, V>, map, BTreeMap::new());
451
452map!(
453 #[cfg(feature = "std")]
454 #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
455 _cx,
456 HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
457 map,
458 HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default())
459);
460
461impl<M> Encode<M> for CString {
462 #[inline]
463 fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
464 where
465 E: Encoder,
466 {
467 encoder.encode_bytes(self.to_bytes_with_nul())
468 }
469}
470
471impl<'de, M> Decode<'de, M> for CString {
472 #[inline]
473 fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
474 where
475 D: Decoder<'de>,
476 {
477 struct Visitor;
478
479 impl<'de, C> UnsizedVisitor<'de, C, [u8]> for Visitor
480 where
481 C: ?Sized + Context,
482 {
483 type Ok = CString;
484
485 #[inline]
486 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
487 write!(f, "a cstring")
488 }
489
490 #[inline]
491 fn visit_owned(self, cx: &C, value: Vec<u8>) -> Result<Self::Ok, C::Error> {
492 CString::from_vec_with_nul(value).map_err(cx.map())
493 }
494
495 #[inline]
496 fn visit_borrowed(self, cx: &C, bytes: &'de [u8]) -> Result<Self::Ok, C::Error> {
497 self.visit_ref(cx, bytes)
498 }
499
500 #[inline]
501 fn visit_ref(self, cx: &C, bytes: &[u8]) -> Result<Self::Ok, C::Error> {
502 Ok(CStr::from_bytes_with_nul(bytes)
503 .map_err(cx.map())?
504 .to_owned())
505 }
506 }
507
508 decoder.decode_bytes(Visitor)
509 }
510}
511
512macro_rules! smart_pointer {
513 ($($ty:ident),* $(,)?) => {
514 $(
515 impl<M, T> Encode<M> for $ty<T>
516 where
517 T: ?Sized + Encode<M>,
518 {
519 #[inline]
520 fn encode<E>(&self, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
521 where
522 E: Encoder<Mode = M>,
523 {
524 self.as_ref().encode(cx, encoder)
525 }
526 }
527
528 impl<'de, M, T> Decode<'de, M> for $ty<T>
529 where
530 T: Decode<'de, M>,
531 {
532 #[inline]
533 fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
534 where
535 D: Decoder<'de, Mode = M>,
536 {
537 Ok($ty::new(decoder.decode()?))
538 }
539 }
540
541 impl<'de, M> DecodeBytes<'de, M> for $ty<[u8]> {
542 #[inline]
543 fn decode_bytes<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
544 where
545 D: Decoder<'de, Mode = M>,
546 {
547 Ok($ty::from(<Vec<u8>>::decode_bytes(cx, decoder)?))
548 }
549 }
550
551 impl<'de, M> Decode<'de, M> for $ty<CStr> {
552 #[inline]
553 fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
554 where
555 D: Decoder<'de, Mode = M>,
556 {
557 Ok($ty::from(CString::decode(cx, decoder)?))
558 }
559 }
560
561 #[cfg(all(feature = "std", any(unix, windows)))]
562 #[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
563 impl<'de, M> Decode<'de, M> for $ty<Path> where PlatformTag: Decode<'de, M> {
564 #[inline]
565 fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
566 where
567 D: Decoder<'de, Mode = M>,
568 {
569 Ok($ty::from(PathBuf::decode(cx, decoder)?))
570 }
571 }
572
573 #[cfg(all(feature = "std", any(unix, windows)))]
574 #[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
575 impl<'de, M> Decode<'de, M> for $ty<OsStr> where PlatformTag: Decode<'de, M> {
576 #[inline]
577 fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
578 where
579 D: Decoder<'de, Mode = M>,
580 {
581 Ok($ty::from(OsString::decode(cx, decoder)?))
582 }
583 }
584 )*
585 };
586}
587
588smart_pointer!(Box, Arc, Rc);
589
590#[cfg(all(feature = "std", any(unix, windows)))]
591#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
592impl<M> Encode<M> for OsStr
593where
594 PlatformTag: Encode<M>,
595{
596 #[cfg(unix)]
597 #[inline]
598 fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
599 where
600 E: Encoder<Mode = M>,
601 {
602 use std::os::unix::ffi::OsStrExt;
603
604 use crate::en::VariantEncoder;
605
606 encoder.encode_variant_fn(|variant| {
607 variant.encode_tag()?.encode(PlatformTag::Unix)?;
608 variant.encode_data()?.encode_bytes(self.as_bytes())?;
609 Ok(())
610 })
611 }
612
613 #[cfg(windows)]
614 #[inline]
615 fn encode<E>(&self, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
616 where
617 E: Encoder<Mode = M>,
618 {
619 use std::os::windows::ffi::OsStrExt;
620
621 use crate::alloc::{Allocator, RawVec};
622 use crate::en::VariantEncoder;
623
624 encoder.encode_variant_fn(|variant| {
625 let mut buf = cx.alloc().new_raw_vec::<u8>();
626 let mut len = 0;
627
628 for w in self.encode_wide() {
629 let bytes = w.to_le_bytes();
630
631 if !buf.resize(len, bytes.len()) {
632 return Err(cx.message("Allocation failed"));
633 }
634
635 unsafe {
637 buf.as_mut_ptr()
638 .add(len)
639 .copy_from_nonoverlapping(bytes.as_ptr(), bytes.len());
640 }
641
642 len += bytes.len();
643 }
644
645 let bytes = unsafe { core::slice::from_raw_parts(buf.as_ptr(), len) };
647
648 variant.encode_tag()?.encode(PlatformTag::Windows)?;
649 variant.encode_data()?.encode_bytes(bytes)?;
650 Ok(())
651 })
652 }
653}
654
655#[cfg(all(feature = "std", any(unix, windows)))]
656#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
657impl<M> Encode<M> for OsString
658where
659 PlatformTag: Encode<M>,
660{
661 #[inline]
662 fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
663 where
664 E: Encoder<Mode = M>,
665 {
666 encoder.encode(self.as_os_str())
667 }
668}
669
670#[cfg(all(feature = "std", any(unix, windows)))]
671#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
672impl<'de, M> Decode<'de, M> for OsString
673where
674 PlatformTag: Decode<'de, M>,
675{
676 #[inline]
677 fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
678 where
679 D: Decoder<'de, Mode = M>,
680 {
681 use crate::de::VariantDecoder;
682
683 decoder.decode_variant(|variant| {
684 let tag = variant.decode_tag()?.decode::<PlatformTag>()?;
685
686 match tag {
687 #[cfg(not(unix))]
688 PlatformTag::Unix => Err(cx.message("Unsupported OsString::Unix variant")),
689 #[cfg(unix)]
690 PlatformTag::Unix => {
691 use std::os::unix::ffi::OsStringExt;
692 Ok(OsString::from_vec(variant.decode_value()?.decode()?))
693 }
694 #[cfg(not(windows))]
695 PlatformTag::Windows => Err(cx.message("Unsupported OsString::Windows variant")),
696 #[cfg(windows)]
697 PlatformTag::Windows => {
698 use std::os::windows::ffi::OsStringExt;
699
700 struct Visitor;
701
702 impl<'de, C> UnsizedVisitor<'de, C, [u8]> for Visitor
703 where
704 C: ?Sized + Context,
705 {
706 type Ok = OsString;
707
708 #[inline]
709 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
710 write!(f, "a literal byte reference")
711 }
712
713 #[inline]
714 fn visit_ref(self, _: &C, bytes: &[u8]) -> Result<Self::Ok, C::Error> {
715 let mut buf = Vec::with_capacity(bytes.len() / 2);
716
717 for pair in bytes.chunks_exact(2) {
718 let &[a, b] = pair else {
719 continue;
720 };
721
722 buf.push(u16::from_le_bytes([a, b]));
723 }
724
725 Ok(OsString::from_wide(&buf))
726 }
727 }
728
729 variant.decode_value()?.decode_bytes(Visitor)
730 }
731 }
732 })
733 }
734}
735
736#[cfg(all(feature = "std", any(unix, windows)))]
737#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
738impl<M> Encode<M> for Path
739where
740 PlatformTag: Encode<M>,
741{
742 #[inline]
743 fn encode<E>(&self, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
744 where
745 E: Encoder<Mode = M>,
746 {
747 self.as_os_str().encode(cx, encoder)
748 }
749}
750
751#[cfg(all(feature = "std", any(unix, windows)))]
752#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
753impl<M> Encode<M> for PathBuf
754where
755 PlatformTag: Encode<M>,
756{
757 #[inline]
758 fn encode<E>(&self, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
759 where
760 E: Encoder<Mode = M>,
761 {
762 self.as_path().encode(cx, encoder)
763 }
764}
765
766#[cfg(all(feature = "std", any(unix, windows)))]
767#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
768impl<'de, M> Decode<'de, M> for PathBuf
769where
770 PlatformTag: Decode<'de, M>,
771{
772 #[inline]
773 fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
774 where
775 D: Decoder<'de, Mode = M>,
776 {
777 Ok(PathBuf::from(decoder.decode::<OsString>()?))
778 }
779}
780
781impl<M> EncodeBytes<M> for Vec<u8> {
782 #[inline]
783 fn encode_bytes<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
784 where
785 E: Encoder<Mode = M>,
786 {
787 encoder.encode_bytes(self.as_slice())
788 }
789}
790
791impl<M> EncodeBytes<M> for Box<[u8]> {
792 #[inline]
793 fn encode_bytes<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
794 where
795 E: Encoder<Mode = M>,
796 {
797 encoder.encode_bytes(self.as_ref())
798 }
799}
800
801impl<'de, M> DecodeBytes<'de, M> for Vec<u8> {
802 #[inline]
803 fn decode_bytes<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
804 where
805 D: Decoder<'de, Mode = M>,
806 {
807 struct Visitor;
808
809 impl<'de, C> UnsizedVisitor<'de, C, [u8]> for Visitor
810 where
811 C: ?Sized + Context,
812 {
813 type Ok = Vec<u8>;
814
815 #[inline]
816 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
817 write!(f, "bytes")
818 }
819
820 #[inline]
821 fn visit_borrowed(self, _: &C, bytes: &'de [u8]) -> Result<Self::Ok, C::Error> {
822 Ok(bytes.to_vec())
823 }
824
825 #[inline]
826 fn visit_ref(self, _: &C, bytes: &[u8]) -> Result<Self::Ok, C::Error> {
827 Ok(bytes.to_vec())
828 }
829 }
830
831 decoder.decode_bytes(Visitor)
832 }
833}
834
835impl<M> EncodeBytes<M> for VecDeque<u8> {
836 #[inline]
837 fn encode_bytes<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
838 where
839 E: Encoder<Mode = M>,
840 {
841 let (first, second) = self.as_slices();
842 encoder.encode_bytes_vectored(self.len(), &[first, second])
843 }
844}
845
846impl<'de, M> DecodeBytes<'de, M> for VecDeque<u8> {
847 #[inline]
848 fn decode_bytes<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
849 where
850 D: Decoder<'de, Mode = M>,
851 {
852 Ok(VecDeque::from(<Vec<u8>>::decode_bytes(cx, decoder)?))
853 }
854}