1use core::ffi::CStr;
2use core::fmt;
3#[cfg(feature = "std")]
4use core::hash::{BuildHasher, Hash};
5
6use rust_alloc::borrow::Cow;
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::alloc::ToOwned;
23use crate::de::{
24 Decode, DecodeBytes, DecodeTrace, Decoder, EntryDecoder, MapDecoder, SequenceDecoder,
25 UnsizedVisitor,
26};
27use crate::en::{
28 Encode, EncodeBytes, EncodePacked, EncodeTrace, Encoder, EntryEncoder, MapEncoder,
29 SequenceEncoder,
30};
31use crate::internal::size_hint;
32use crate::{Allocator, Context};
33
34#[cfg(all(feature = "std", any(unix, windows)))]
35use super::PlatformTag;
36
37impl<M> Encode<M> for String {
38 type Encode = str;
39
40 const IS_BITWISE_ENCODE: bool = false;
41
42 #[inline]
43 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
44 where
45 E: Encoder<Mode = M>,
46 {
47 self.as_str().encode(encoder)
48 }
49
50 #[inline]
51 fn as_encode(&self) -> &Self::Encode {
52 self
53 }
54}
55
56impl<'de, M, A> Decode<'de, M, A> for String
57where
58 A: Allocator,
59{
60 const IS_BITWISE_DECODE: bool = false;
61
62 #[inline]
63 fn decode<D>(decoder: D) -> Result<Self, D::Error>
64 where
65 D: Decoder<'de, Mode = M>,
66 {
67 struct Visitor;
68
69 #[crate::de::unsized_visitor(crate)]
70 impl<C> UnsizedVisitor<'_, C, str> for Visitor
71 where
72 C: Context,
73 {
74 type Ok = String;
75
76 #[inline]
77 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 write!(f, "string")
79 }
80
81 #[inline]
82 fn visit_ref(self, _: C, string: &str) -> Result<Self::Ok, Self::Error> {
83 use rust_alloc::borrow::ToOwned;
84 Ok(string.to_owned())
85 }
86 }
87
88 decoder.decode_string(Visitor)
89 }
90}
91
92impl<'de, M, A> Decode<'de, M, A> for Box<str>
93where
94 A: Allocator,
95{
96 const IS_BITWISE_DECODE: bool = false;
97
98 #[inline]
99 fn decode<D>(decoder: D) -> Result<Self, D::Error>
100 where
101 D: Decoder<'de, Mode = M>,
102 {
103 Ok(decoder.decode::<String>()?.into())
104 }
105}
106
107macro_rules! cow {
108 (
109 $encode:ident :: $encode_fn:ident,
110 $as_encode:ident,
111 $decode:ident :: $decode_fn:ident,
112 $encode_packed:ident,
113 $decode_packed:ident,
114 $ty:ty, $source:ty,
115 $decode_method:ident, $cx:pat,
116 |$owned:ident| $owned_expr:expr,
117 |$borrowed:ident| $borrowed_expr:expr,
118 |$reference:ident| $reference_expr:expr $(,)?
119 ) => {
120 impl<M> $encode<M> for Cow<'_, $ty> {
121 const $encode_packed: bool = false;
122
123 type $encode = $ty;
124
125 #[inline]
126 fn $encode_fn<E>(&self, encoder: E) -> Result<(), E::Error>
127 where
128 E: Encoder<Mode = M>,
129 {
130 self.as_ref().$encode_fn(encoder)
131 }
132
133 #[inline]
134 fn $as_encode(&self) -> &Self::$encode {
135 self
136 }
137 }
138
139 impl<'de, M, A> $decode<'de, M, A> for Cow<'de, $ty>
140 where
141 A: Allocator,
142 {
143 const $decode_packed: bool = false;
144
145 #[inline]
146 fn $decode_fn<D>(decoder: D) -> Result<Self, D::Error>
147 where
148 D: Decoder<'de, Mode = M, Allocator = A>,
149 {
150 struct Visitor;
151
152 #[crate::de::unsized_visitor(crate)]
153 impl<'de, C> UnsizedVisitor<'de, C, $source> for Visitor
154 where
155 C: Context,
156 {
157 type Ok = Cow<'de, $ty>;
158
159 #[inline]
160 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 write!(f, "a string")
162 }
163
164 #[inline]
165 fn visit_owned(
166 self,
167 $cx: C,
168 $owned: <$source as ToOwned>::Owned<Self::Allocator>,
169 ) -> Result<Self::Ok, Self::Error> {
170 Ok($owned_expr)
171 }
172
173 #[inline]
174 fn visit_borrowed(
175 self,
176 $cx: C,
177 $borrowed: &'de $source,
178 ) -> Result<Self::Ok, Self::Error> {
179 Ok($borrowed_expr)
180 }
181
182 #[inline]
183 fn visit_ref(
184 self,
185 $cx: C,
186 $reference: &$source,
187 ) -> Result<Self::Ok, Self::Error> {
188 Ok($reference_expr)
189 }
190 }
191
192 decoder.$decode_method(Visitor)
193 }
194 }
195 };
196}
197
198cow! {
199 Encode::encode,
200 as_encode,
201 Decode::decode,
202 IS_BITWISE_ENCODE,
203 IS_BITWISE_DECODE,
204 str, str, decode_string, _,
205 |owned| {
206 match owned.into_std() {
207 Ok(owned) => Cow::Owned(owned),
208 Err(owned) => {
209 Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(owned.as_str()))
210 }
211 }
212 },
213 |borrowed| Cow::Borrowed(borrowed),
214 |reference| Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(reference))
215}
216
217cow! {
218 Encode::encode,
219 as_encode,
220 Decode::decode,
221 IS_BITWISE_ENCODE,
222 IS_BITWISE_DECODE,
223 CStr, [u8], decode_bytes, cx,
224 |owned| {
225 match owned.into_std() {
226 Ok(owned) => Cow::Owned(CString::from_vec_with_nul(owned).map_err(cx.map())?),
227 Err(reference) => {
228 let value = CStr::from_bytes_with_nul(&reference).map_err(cx.map())?;
229 Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(value))
230 }
231 }
232 },
233 |borrowed| Cow::Borrowed(CStr::from_bytes_with_nul(borrowed).map_err(cx.map())?),
234 |reference| {
235 let value = CStr::from_bytes_with_nul(reference).map_err(cx.map())?;
236 Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(value))
237 }
238}
239
240cow! {
241 EncodeBytes::encode_bytes,
242 as_encode_bytes,
243 DecodeBytes::decode_bytes,
244 ENCODE_BYTES_PACKED,
245 DECODE_BYTES_PACKED,
246 [u8], [u8], decode_bytes, _,
247 |owned| {
248 match owned.into_std() {
249 Ok(owned) => Cow::Owned(owned),
250 Err(owned) => Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(owned.as_slice())),
251 }
252 },
253 |borrowed| Cow::Borrowed(borrowed),
254 |reference| Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(reference)),
255}
256
257macro_rules! sequence {
258 (
259 $(#[$($meta:meta)*])*
260 $cx:ident,
261 $ty:ident <T $(: $trait0:ident $(+ $trait:ident)*)? $(, $extra:ident: $extra_bound0:ident $(+ $extra_bound:ident)*)*>,
262 $insert:ident,
263 $access:ident,
264 $factory:expr
265 ) => {
266 $(#[$($meta)*])*
267 impl<M, T $(, $extra)*> Encode<M> for $ty<T $(, $extra)*>
268 where
269 T: Encode<M>,
270 $($extra: $extra_bound0 $(+ $extra_bound)*),*
271 {
272 const IS_BITWISE_ENCODE: bool = false;
273
274 type Encode = Self;
275
276 #[inline]
277 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
278 where
279 E: Encoder<Mode = M>,
280 {
281 let $cx = encoder.cx();
282
283 encoder.encode_sequence_fn(self.len(), |seq| {
284 let mut index = 0;
285
286 for value in self {
287 $cx.enter_sequence_index(index);
288 seq.push(value)?;
289 $cx.leave_sequence_index();
290 index = index.wrapping_add(1);
291 }
292
293 Ok(())
294 })
295 }
296
297 #[inline]
298 fn as_encode(&self) -> &Self::Encode {
299 self
300 }
301 }
302
303 $(#[$($meta)*])*
304 impl<'de, M, A, T $(, $extra)*> Decode<'de, M, A> for $ty<T $(, $extra)*>
305 where
306 A: Allocator,
307 T: Decode<'de, M, A> $(+ $trait0 $(+ $trait)*)*,
308 $($extra: $extra_bound0 $(+ $extra_bound)*),*
309 {
310 const IS_BITWISE_DECODE: bool = false;
311
312 #[inline]
313 fn decode<D>(decoder: D) -> Result<Self, D::Error>
314 where
315 D: Decoder<'de, Mode = M, Allocator = A>,
316 {
317 let $cx = decoder.cx();
318
319 decoder.decode_sequence(|$access| {
320 let mut out = $factory;
321
322 let mut index = 0;
323
324 while let Some(value) = $access.try_decode_next()? {
325 $cx.enter_sequence_index(index);
326 out.$insert(value.decode()?);
327 $cx.leave_sequence_index();
328 index = index.wrapping_add(1);
329 }
330
331 Ok(out)
332 })
333 }
334 }
335
336 $(#[$($meta)*])*
337 impl<M, T $(, $extra)*> EncodePacked<M> for $ty<T $(, $extra)*>
338 where
339 T: Encode<M>,
340 $($extra: $extra_bound0 $(+ $extra_bound)*),*
341 {
342 #[inline]
343 fn encode_packed<E>(&self, encoder: E) -> Result<(), E::Error>
344 where
345 E: Encoder<Mode = M>,
346 {
347 let $cx = encoder.cx();
348
349 encoder.encode_pack_fn(|pack| {
350 let mut index = 0;
351
352 for value in self {
353 $cx.enter_sequence_index(index);
354 pack.push(value)?;
355 $cx.leave_sequence_index();
356 index = index.wrapping_add(1);
357 }
358
359 Ok(())
360 })
361 }
362 }
363 }
364}
365
366crate::internal::macros::slice_sequence! {
367 cx,
368 Vec<T>,
369 || Vec::new(),
370 |vec, value| vec.push(value),
371 |vec, capacity| vec.reserve(capacity),
372 |size| Vec::with_capacity(size),
373}
374
375impl<M, T> Encode<M> for VecDeque<T>
376where
377 T: Encode<M>,
378{
379 type Encode = Self;
380
381 const IS_BITWISE_ENCODE: bool = false;
382
383 #[inline]
384 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
385 where
386 E: Encoder<Mode = M>,
387 {
388 let (a, b) = self.as_slices();
389 encoder.encode_slices(self.len(), [a, b])
390 }
391
392 #[inline]
393 fn as_encode(&self) -> &Self::Encode {
394 self
395 }
396}
397
398impl<'de, M, A, T> Decode<'de, M, A> for VecDeque<T>
399where
400 A: Allocator,
401 T: Decode<'de, M, A>,
402{
403 const IS_BITWISE_DECODE: bool = false;
404
405 #[inline]
406 fn decode<D>(decoder: D) -> Result<Self, D::Error>
407 where
408 D: Decoder<'de, Mode = M, Allocator = A>,
409 {
410 Ok(VecDeque::from(Vec::decode(decoder)?))
411 }
412}
413
414impl<M, T> EncodePacked<M> for VecDeque<T>
415where
416 T: Encode<M>,
417{
418 #[inline]
419 fn encode_packed<E>(&self, encoder: E) -> Result<(), E::Error>
420 where
421 E: Encoder<Mode = M>,
422 {
423 encoder.encode_pack_fn(|pack| {
424 let (a, b) = self.as_slices();
425 pack.encode_slices([a, b])
426 })
427 }
428}
429
430sequence! {
431 cx,
432 BTreeSet<T: Ord>,
433 insert,
434 seq,
435 BTreeSet::new()
436}
437
438sequence! {
439 #[cfg(feature = "std")]
440 #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
441 cx,
442 HashSet<T: Eq + Hash, S: BuildHasher + Default>,
443 insert,
444 seq,
445 HashSet::with_capacity_and_hasher(size_hint::cautious::<T>(seq.size_hint()), S::default())
446}
447
448sequence! {
449 cx,
450 BinaryHeap<T: Ord>,
451 push,
452 seq,
453 BinaryHeap::with_capacity(size_hint::cautious::<T>(seq.size_hint()))
454}
455
456macro_rules! map {
457 (
458 $(#[$($meta:meta)*])*
459 $cx:ident,
460 $ty:ident<K $(: $key_bound0:ident $(+ $key_bound:ident)*)?, V $(, $extra:ident: $extra_bound0:ident $(+ $extra_bound:ident)*)*>,
461 $access:ident,
462 $with_capacity:expr
463 ) => {
464 $(#[$($meta)*])*
465 impl<'de, M, K, V $(, $extra)*> Encode<M> for $ty<K, V $(, $extra)*>
466 where
467 K: Encode<M>,
468 V: Encode<M>,
469 $($extra: $extra_bound0 $(+ $extra_bound)*),*
470 {
471 const IS_BITWISE_ENCODE: bool = false;
472
473 type Encode = Self;
474
475 #[inline]
476 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
477 where
478 E: Encoder<Mode = M>,
479 {
480 let hint = self.len();
481
482 encoder.encode_map_fn(hint, |map| {
483 for (k, v) in self {
484 map.insert_entry(k, v)?;
485 }
486
487 Ok(())
488 })
489 }
490
491 #[inline]
492 fn as_encode(&self) -> &Self::Encode {
493 self
494 }
495 }
496
497 $(#[$($meta)*])*
498 impl<'de, M, K, V $(, $extra)*> EncodeTrace<M> for $ty<K, V $(, $extra)*>
499 where
500 K: fmt::Display + Encode<M>,
501 V: Encode<M>,
502 $($extra: $extra_bound0 $(+ $extra_bound)*),*
503 {
504 #[inline]
505 fn trace_encode<E>(&self, encoder: E) -> Result<(), E::Error>
506 where
507 E: Encoder<Mode = M>,
508 {
509 let hint = self.len();
510
511 let $cx = encoder.cx();
512
513 encoder.encode_map_fn(hint, |map| {
514 for (k, v) in self {
515 $cx.enter_map_key(k);
516 map.encode_entry_fn(|entry| {
517 entry.encode_key()?.encode(k)?;
518 entry.encode_value()?.encode(v)?;
519 Ok(())
520 })?;
521 $cx.leave_map_key();
522 }
523
524 Ok(())
525 })
526 }
527 }
528
529 $(#[$($meta)*])*
530 impl<'de, K, V, A, M $(, $extra)*> Decode<'de, M, A> for $ty<K, V $(, $extra)*>
531 where
532 A: Allocator,
533 K: Decode<'de, M, A> $(+ $key_bound0 $(+ $key_bound)*)*,
534 V: Decode<'de, M, A>,
535 $($extra: $extra_bound0 $(+ $extra_bound)*),*
536 {
537 const IS_BITWISE_DECODE: bool = false;
538
539 #[inline]
540 fn decode<D>(decoder: D) -> Result<Self, D::Error>
541 where
542 D: Decoder<'de, Mode = M, Allocator = A>,
543 {
544 decoder.decode_map(|$access| {
545 let mut out = $with_capacity;
546
547 while let Some((key, value)) = $access.entry()? {
548 out.insert(key, value);
549 }
550
551 Ok(out)
552 })
553 }
554 }
555
556 $(#[$($meta)*])*
557 impl<'de, K, V, A, M $(, $extra)*> DecodeTrace<'de, M, A> for $ty<K, V $(, $extra)*>
558 where
559 A: Allocator,
560 K: fmt::Display + Decode<'de, M, A> $(+ $key_bound0 $(+ $key_bound)*)*,
561 V: Decode<'de, M, A>,
562 $($extra: $extra_bound0 $(+ $extra_bound)*),*
563 {
564 #[inline]
565 fn trace_decode<D>(decoder: D) -> Result<Self, D::Error>
566 where
567 D: Decoder<'de, Mode = M, Allocator = A>,
568 {
569 let $cx = decoder.cx();
570
571 decoder.decode_map(|$access| {
572 let mut out = $with_capacity;
573
574 while let Some(mut entry) = $access.decode_entry()? {
575 let key = entry.decode_key()?.decode()?;
576 $cx.enter_map_key(&key);
577 let value = entry.decode_value()?.decode()?;
578 out.insert(key, value);
579 $cx.leave_map_key();
580 }
581
582 Ok(out)
583 })
584 }
585 }
586 }
587}
588
589map!(_cx, BTreeMap<K: Ord, V>, map, BTreeMap::new());
590
591map!(
592 #[cfg(feature = "std")]
593 #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
594 _cx,
595 HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
596 map,
597 HashMap::with_capacity_and_hasher(size_hint::cautious::<(K, V)>(map.size_hint()), S::default())
598);
599
600impl<M> Encode<M> for CString {
601 type Encode = CStr;
602
603 const IS_BITWISE_ENCODE: bool = false;
604
605 #[inline]
606 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
607 where
608 E: Encoder,
609 {
610 encoder.encode_bytes(self.to_bytes_with_nul())
611 }
612
613 #[inline]
614 fn as_encode(&self) -> &Self::Encode {
615 self
616 }
617}
618
619impl<'de, M, A> Decode<'de, M, A> for CString
620where
621 A: Allocator,
622{
623 const IS_BITWISE_DECODE: bool = false;
624
625 #[inline]
626 fn decode<D>(decoder: D) -> Result<Self, D::Error>
627 where
628 D: Decoder<'de, Allocator = A>,
629 {
630 struct Visitor;
631
632 #[crate::de::unsized_visitor(crate)]
633 impl<C> UnsizedVisitor<'_, C, [u8]> for Visitor
634 where
635 C: Context,
636 {
637 type Ok = CString;
638
639 #[inline]
640 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
641 write!(f, "a cstring")
642 }
643
644 #[inline]
645 fn visit_owned(
646 self,
647 cx: C,
648 value: crate::alloc::Vec<u8, Self::Allocator>,
649 ) -> Result<Self::Ok, Self::Error> {
650 match value.into_std() {
651 Ok(value) => CString::from_vec_with_nul(value).map_err(cx.map()),
652 Err(value) => self.visit_ref(cx, &value),
653 }
654 }
655
656 #[inline]
657 fn visit_ref(self, cx: C, bytes: &[u8]) -> Result<Self::Ok, Self::Error> {
658 let value = CStr::from_bytes_with_nul(bytes).map_err(cx.map())?;
659 Ok(rust_alloc::borrow::ToOwned::to_owned(value))
660 }
661 }
662
663 decoder.decode_bytes(Visitor)
664 }
665}
666
667macro_rules! smart_pointer {
668 ($($ty:ident),* $(,)?) => {
669 $(
670 impl<M, T> Encode<M> for $ty<T>
671 where
672 T: ?Sized + Encode<M>,
673 {
674 const IS_BITWISE_ENCODE: bool = false;
675
676 type Encode = T;
677
678 #[inline]
679 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
680 where
681 E: Encoder<Mode = M>,
682 {
683 self.as_ref().encode(encoder)
684 }
685
686 #[inline]
687 fn as_encode(&self) -> &Self::Encode {
688 self
689 }
690 }
691
692 impl<'de, M, A, T> Decode<'de, M, A> for $ty<T>
693 where
694 A: Allocator,
695 T: Decode<'de, M, A>,
696 {
697 const IS_BITWISE_DECODE: bool = false;
698
699 #[inline]
700 fn decode<D>(decoder: D) -> Result<Self, D::Error>
701 where
702 D: Decoder<'de, Mode = M, Allocator = A>,
703 {
704 Ok($ty::new(decoder.decode()?))
705 }
706 }
707
708 impl<'de, M, A, T> Decode<'de, M, A> for $ty<[T]>
709 where
710 A: Allocator,
711 T: Decode<'de, M, A>,
712 {
713 const IS_BITWISE_DECODE: bool = false;
714
715 #[inline]
716 fn decode<D>(decoder: D) -> Result<Self, D::Error>
717 where
718 D: Decoder<'de, Mode = M, Allocator = A>,
719 {
720 Ok($ty::from(Vec::<T>::decode(decoder)?))
721 }
722 }
723
724 impl<'de, M, A> DecodeBytes<'de, M, A> for $ty<[u8]>
725 where
726 A: Allocator
727 {
728 const DECODE_BYTES_PACKED: bool = false;
729
730 #[inline]
731 fn decode_bytes<D>(decoder: D) -> Result<Self, D::Error>
732 where
733 D: Decoder<'de, Mode = M, Allocator = A>,
734 {
735 Ok($ty::from(<Vec<u8>>::decode_bytes(decoder)?))
736 }
737 }
738
739 impl<'de, M, A> Decode<'de, M, A> for $ty<CStr>
740 where
741 A: Allocator,
742 {
743 const IS_BITWISE_DECODE: bool = false;
744
745 #[inline]
746 fn decode<D>(decoder: D) -> Result<Self, D::Error>
747 where
748 D: Decoder<'de, Mode = M, Allocator = A>,
749 {
750 Ok($ty::from(CString::decode(decoder)?))
751 }
752 }
753
754 #[cfg(all(feature = "std", any(unix, windows)))]
755 #[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
756 impl<'de, M, A> Decode<'de, M, A> for $ty<Path>
757 where
758 A: Allocator,
759 PlatformTag: Decode<'de, M, A>,
760 {
761 const IS_BITWISE_DECODE: bool = false;
762
763 #[inline]
764 fn decode<D>(decoder: D) -> Result<Self, D::Error>
765 where
766 D: Decoder<'de, Mode = M, Allocator = A>,
767 {
768 Ok($ty::from(PathBuf::decode(decoder)?))
769 }
770 }
771
772 #[cfg(all(feature = "std", any(unix, windows)))]
773 #[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
774 impl<'de, M, A> Decode<'de, M, A> for $ty<OsStr>
775 where
776 A: Allocator,
777 PlatformTag: Decode<'de, M, A>,
778 {
779 const IS_BITWISE_DECODE: bool = false;
780
781 #[inline]
782 fn decode<D>(decoder: D) -> Result<Self, D::Error>
783 where
784 D: Decoder<'de, Mode = M, Allocator = A>,
785 {
786 Ok($ty::from(OsString::decode(decoder)?))
787 }
788 }
789 )*
790 };
791}
792
793smart_pointer!(Box, Arc, Rc);
794
795#[cfg(all(feature = "std", any(unix, windows)))]
796#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
797impl<M> Encode<M> for OsStr
798where
799 PlatformTag: Encode<M>,
800{
801 type Encode = Self;
802
803 const IS_BITWISE_ENCODE: bool = false;
804
805 #[cfg(unix)]
806 #[inline]
807 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
808 where
809 E: Encoder<Mode = M>,
810 {
811 use std::os::unix::ffi::OsStrExt;
812
813 use crate::en::VariantEncoder;
814
815 encoder.encode_variant_fn(|variant| {
816 variant.encode_tag()?.encode(PlatformTag::Unix)?;
817 variant.encode_data()?.encode_bytes(self.as_bytes())?;
818 Ok(())
819 })
820 }
821
822 #[cfg(windows)]
823 #[inline]
824 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
825 where
826 E: Encoder<Mode = M>,
827 {
828 use std::os::windows::ffi::OsStrExt;
829
830 use crate::alloc::Alloc;
831 use crate::en::VariantEncoder;
832
833 let cx = encoder.cx();
834
835 encoder.encode_variant_fn(|variant| {
836 let mut buf = cx.alloc().alloc_empty::<u8>();
837 let mut len = 0;
838
839 for w in self.encode_wide() {
840 let bytes = w.to_le_bytes();
841
842 buf.resize(len, bytes.len()).map_err(cx.map())?;
843
844 unsafe {
846 buf.as_mut_ptr()
847 .add(len)
848 .copy_from_nonoverlapping(bytes.as_ptr(), bytes.len());
849 }
850
851 len += bytes.len();
852 }
853
854 let bytes = unsafe { core::slice::from_raw_parts(buf.as_ptr(), len) };
856
857 variant.encode_tag()?.encode(&PlatformTag::Windows)?;
858 variant.encode_data()?.encode_bytes(bytes)?;
859 Ok(())
860 })
861 }
862
863 #[inline]
864 fn as_encode(&self) -> &Self::Encode {
865 self
866 }
867}
868
869#[cfg(all(feature = "std", any(unix, windows)))]
870#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
871impl<M> Encode<M> for OsString
872where
873 PlatformTag: Encode<M>,
874{
875 type Encode = OsStr;
876
877 const IS_BITWISE_ENCODE: bool = false;
878
879 #[inline]
880 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
881 where
882 E: Encoder<Mode = M>,
883 {
884 encoder.encode(self.as_os_str())
885 }
886
887 #[inline]
888 fn as_encode(&self) -> &Self::Encode {
889 self
890 }
891}
892
893#[cfg(all(feature = "std", any(unix, windows)))]
894#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
895impl<'de, M, A> Decode<'de, M, A> for OsString
896where
897 A: Allocator,
898 PlatformTag: Decode<'de, M, A>,
899{
900 const IS_BITWISE_DECODE: bool = false;
901
902 #[inline]
903 fn decode<D>(decoder: D) -> Result<Self, D::Error>
904 where
905 D: Decoder<'de, Mode = M, Allocator = A>,
906 {
907 use crate::de::VariantDecoder;
908
909 let cx = decoder.cx();
910
911 decoder.decode_variant(|variant| {
912 let tag = variant.decode_tag()?.decode::<PlatformTag>()?;
913
914 match tag {
915 #[cfg(not(unix))]
916 PlatformTag::Unix => Err(cx.message("Unsupported OsString::Unix variant")),
917 #[cfg(unix)]
918 PlatformTag::Unix => {
919 use std::os::unix::ffi::OsStringExt;
920 Ok(OsString::from_vec(variant.decode_value()?.decode()?))
921 }
922 #[cfg(not(windows))]
923 PlatformTag::Windows => Err(cx.message("Unsupported OsString::Windows variant")),
924 #[cfg(windows)]
925 PlatformTag::Windows => {
926 use std::os::windows::ffi::OsStringExt;
927
928 struct Visitor;
929
930 #[crate::de::unsized_visitor(crate)]
931 impl<C> UnsizedVisitor<'_, C, [u8]> for Visitor
932 where
933 C: Context,
934 {
935 type Ok = OsString;
936
937 #[inline]
938 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
939 write!(f, "a literal byte reference")
940 }
941
942 #[inline]
943 fn visit_ref(self, _: C, bytes: &[u8]) -> Result<Self::Ok, Self::Error> {
944 let mut buf = Vec::with_capacity(bytes.len() / 2);
945
946 for pair in bytes.chunks_exact(2) {
947 let &[a, b] = pair else {
948 continue;
949 };
950
951 buf.push(u16::from_le_bytes([a, b]));
952 }
953
954 Ok(OsString::from_wide(&buf))
955 }
956 }
957
958 variant.decode_value()?.decode_bytes(Visitor)
959 }
960 }
961 })
962 }
963}
964
965#[cfg(all(feature = "std", any(unix, windows)))]
966#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
967impl<M> Encode<M> for Path
968where
969 PlatformTag: Encode<M>,
970{
971 type Encode = Self;
972
973 const IS_BITWISE_ENCODE: bool = false;
974
975 #[inline]
976 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
977 where
978 E: Encoder<Mode = M>,
979 {
980 self.as_os_str().encode(encoder)
981 }
982
983 #[inline]
984 fn as_encode(&self) -> &Self::Encode {
985 self
986 }
987}
988
989#[cfg(all(feature = "std", any(unix, windows)))]
990#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
991impl<M> Encode<M> for PathBuf
992where
993 PlatformTag: Encode<M>,
994{
995 type Encode = Self;
996
997 const IS_BITWISE_ENCODE: bool = false;
998
999 #[inline]
1000 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
1001 where
1002 E: Encoder<Mode = M>,
1003 {
1004 self.as_path().encode(encoder)
1005 }
1006
1007 #[inline]
1008 fn as_encode(&self) -> &Self::Encode {
1009 self
1010 }
1011}
1012
1013#[cfg(all(feature = "std", any(unix, windows)))]
1014#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
1015impl<'de, M, A> Decode<'de, M, A> for PathBuf
1016where
1017 A: Allocator,
1018 PlatformTag: Decode<'de, M, A>,
1019{
1020 const IS_BITWISE_DECODE: bool = false;
1021
1022 #[inline]
1023 fn decode<D>(decoder: D) -> Result<Self, D::Error>
1024 where
1025 D: Decoder<'de, Mode = M, Allocator = A>,
1026 {
1027 Ok(PathBuf::from(decoder.decode::<OsString>()?))
1028 }
1029}
1030
1031impl<M> EncodeBytes<M> for Vec<u8> {
1032 const ENCODE_BYTES_PACKED: bool = false;
1033
1034 type EncodeBytes = [u8];
1035
1036 #[inline]
1037 fn encode_bytes<E>(&self, encoder: E) -> Result<(), E::Error>
1038 where
1039 E: Encoder<Mode = M>,
1040 {
1041 encoder.encode_bytes(self.as_slice())
1042 }
1043
1044 #[inline]
1045 fn as_encode_bytes(&self) -> &Self::EncodeBytes {
1046 self
1047 }
1048}
1049
1050impl<M> EncodeBytes<M> for Box<[u8]> {
1051 const ENCODE_BYTES_PACKED: bool = false;
1052
1053 type EncodeBytes = [u8];
1054
1055 #[inline]
1056 fn encode_bytes<E>(&self, encoder: E) -> Result<(), E::Error>
1057 where
1058 E: Encoder<Mode = M>,
1059 {
1060 encoder.encode_bytes(self.as_ref())
1061 }
1062
1063 #[inline]
1064 fn as_encode_bytes(&self) -> &Self::EncodeBytes {
1065 self
1066 }
1067}
1068
1069impl<'de, M, A> DecodeBytes<'de, M, A> for Vec<u8>
1070where
1071 A: Allocator,
1072{
1073 const DECODE_BYTES_PACKED: bool = false;
1074
1075 #[inline]
1076 fn decode_bytes<D>(decoder: D) -> Result<Self, D::Error>
1077 where
1078 D: Decoder<'de, Mode = M, Allocator = A>,
1079 {
1080 struct Visitor;
1081
1082 #[crate::de::unsized_visitor(crate)]
1083 impl<'de, C> UnsizedVisitor<'de, C, [u8]> for Visitor
1084 where
1085 C: Context,
1086 {
1087 type Ok = Vec<u8>;
1088
1089 #[inline]
1090 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1091 write!(f, "bytes")
1092 }
1093
1094 #[inline]
1095 fn visit_borrowed(self, _: C, bytes: &'de [u8]) -> Result<Self::Ok, Self::Error> {
1096 Ok(bytes.to_vec())
1097 }
1098
1099 #[inline]
1100 fn visit_ref(self, _: C, bytes: &[u8]) -> Result<Self::Ok, Self::Error> {
1101 Ok(bytes.to_vec())
1102 }
1103 }
1104
1105 decoder.decode_bytes(Visitor)
1106 }
1107}
1108
1109impl<M> EncodeBytes<M> for VecDeque<u8> {
1110 const ENCODE_BYTES_PACKED: bool = false;
1111
1112 type EncodeBytes = VecDeque<u8>;
1113
1114 #[inline]
1115 fn encode_bytes<E>(&self, encoder: E) -> Result<(), E::Error>
1116 where
1117 E: Encoder<Mode = M>,
1118 {
1119 let (first, second) = self.as_slices();
1120 encoder.encode_bytes_vectored(self.len(), &[first, second])
1121 }
1122
1123 #[inline]
1124 fn as_encode_bytes(&self) -> &Self::EncodeBytes {
1125 self
1126 }
1127}
1128
1129impl<'de, M, A> DecodeBytes<'de, M, A> for VecDeque<u8>
1130where
1131 A: Allocator,
1132{
1133 const DECODE_BYTES_PACKED: bool = false;
1134
1135 #[inline]
1136 fn decode_bytes<D>(decoder: D) -> Result<Self, D::Error>
1137 where
1138 D: Decoder<'de, Mode = M, Allocator = A>,
1139 {
1140 Ok(VecDeque::from(<Vec<u8>>::decode_bytes(decoder)?))
1141 }
1142}