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
107impl<'de, M, A, T> Decode<'de, M, A> for Box<[T]>
108where
109 A: Allocator,
110 T: Decode<'de, M, A>,
111{
112 const IS_BITWISE_DECODE: bool = false;
113
114 #[inline]
115 fn decode<D>(decoder: D) -> Result<Self, D::Error>
116 where
117 D: Decoder<'de, Mode = M, Allocator = A>,
118 {
119 Ok(decoder.decode::<Vec<T>>()?.into())
120 }
121}
122
123macro_rules! cow {
124 (
125 $encode:ident :: $encode_fn:ident,
126 $as_encode:ident,
127 $decode:ident :: $decode_fn:ident,
128 $encode_packed:ident,
129 $decode_packed:ident,
130 $ty:ty, $source:ty,
131 $decode_method:ident, $cx:pat,
132 |$owned:ident| $owned_expr:expr,
133 |$borrowed:ident| $borrowed_expr:expr,
134 |$reference:ident| $reference_expr:expr $(,)?
135 ) => {
136 impl<M> $encode<M> for Cow<'_, $ty> {
137 const $encode_packed: bool = false;
138
139 type $encode = $ty;
140
141 #[inline]
142 fn $encode_fn<E>(&self, encoder: E) -> Result<(), E::Error>
143 where
144 E: Encoder<Mode = M>,
145 {
146 self.as_ref().$encode_fn(encoder)
147 }
148
149 #[inline]
150 fn $as_encode(&self) -> &Self::$encode {
151 self
152 }
153 }
154
155 impl<'de, M, A> $decode<'de, M, A> for Cow<'de, $ty>
156 where
157 A: Allocator,
158 {
159 const $decode_packed: bool = false;
160
161 #[inline]
162 fn $decode_fn<D>(decoder: D) -> Result<Self, D::Error>
163 where
164 D: Decoder<'de, Mode = M, Allocator = A>,
165 {
166 struct Visitor;
167
168 #[crate::de::unsized_visitor(crate)]
169 impl<'de, C> UnsizedVisitor<'de, C, $source> for Visitor
170 where
171 C: Context,
172 {
173 type Ok = Cow<'de, $ty>;
174
175 #[inline]
176 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 write!(f, "a string")
178 }
179
180 #[inline]
181 fn visit_owned(
182 self,
183 $cx: C,
184 $owned: <$source as ToOwned>::Owned<Self::Allocator>,
185 ) -> Result<Self::Ok, Self::Error> {
186 Ok($owned_expr)
187 }
188
189 #[inline]
190 fn visit_borrowed(
191 self,
192 $cx: C,
193 $borrowed: &'de $source,
194 ) -> Result<Self::Ok, Self::Error> {
195 Ok($borrowed_expr)
196 }
197
198 #[inline]
199 fn visit_ref(
200 self,
201 $cx: C,
202 $reference: &$source,
203 ) -> Result<Self::Ok, Self::Error> {
204 Ok($reference_expr)
205 }
206 }
207
208 decoder.$decode_method(Visitor)
209 }
210 }
211 };
212}
213
214cow! {
215 Encode::encode,
216 as_encode,
217 Decode::decode,
218 IS_BITWISE_ENCODE,
219 IS_BITWISE_DECODE,
220 str, str, decode_string, _,
221 |owned| {
222 match owned.into_std() {
223 Ok(owned) => Cow::Owned(owned),
224 Err(owned) => {
225 Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(owned.as_str()))
226 }
227 }
228 },
229 |borrowed| Cow::Borrowed(borrowed),
230 |reference| Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(reference))
231}
232
233cow! {
234 Encode::encode,
235 as_encode,
236 Decode::decode,
237 IS_BITWISE_ENCODE,
238 IS_BITWISE_DECODE,
239 CStr, [u8], decode_bytes, cx,
240 |owned| {
241 match owned.into_std() {
242 Ok(owned) => Cow::Owned(CString::from_vec_with_nul(owned).map_err(cx.map())?),
243 Err(reference) => {
244 let value = CStr::from_bytes_with_nul(&reference).map_err(cx.map())?;
245 Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(value))
246 }
247 }
248 },
249 |borrowed| Cow::Borrowed(CStr::from_bytes_with_nul(borrowed).map_err(cx.map())?),
250 |reference| {
251 let value = CStr::from_bytes_with_nul(reference).map_err(cx.map())?;
252 Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(value))
253 }
254}
255
256cow! {
257 EncodeBytes::encode_bytes,
258 as_encode_bytes,
259 DecodeBytes::decode_bytes,
260 ENCODE_BYTES_PACKED,
261 DECODE_BYTES_PACKED,
262 [u8], [u8], decode_bytes, _,
263 |owned| {
264 match owned.into_std() {
265 Ok(owned) => Cow::Owned(owned),
266 Err(owned) => Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(owned.as_slice())),
267 }
268 },
269 |borrowed| Cow::Borrowed(borrowed),
270 |reference| Cow::Owned(rust_alloc::borrow::ToOwned::to_owned(reference)),
271}
272
273macro_rules! sequence {
274 (
275 $(#[$($meta:meta)*])*
276 $cx:ident,
277 $ty:ident <T $(: $trait0:ident $(+ $trait:ident)*)? $(, $extra:ident: $extra_bound0:ident $(+ $extra_bound:ident)*)*>,
278 $insert:ident,
279 $access:ident,
280 $factory:expr
281 ) => {
282 $(#[$($meta)*])*
283 impl<M, T $(, $extra)*> Encode<M> for $ty<T $(, $extra)*>
284 where
285 T: Encode<M>,
286 $($extra: $extra_bound0 $(+ $extra_bound)*),*
287 {
288 const IS_BITWISE_ENCODE: bool = false;
289
290 type Encode = Self;
291
292 #[inline]
293 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
294 where
295 E: Encoder<Mode = M>,
296 {
297 let $cx = encoder.cx();
298
299 encoder.encode_sequence_fn(self.len(), |seq| {
300 let mut index = 0;
301
302 for value in self {
303 $cx.enter_sequence_index(index);
304 seq.push(value)?;
305 $cx.leave_sequence_index();
306 index = index.wrapping_add(1);
307 }
308
309 Ok(())
310 })
311 }
312
313 #[inline]
314 fn as_encode(&self) -> &Self::Encode {
315 self
316 }
317 }
318
319 $(#[$($meta)*])*
320 impl<'de, M, A, T $(, $extra)*> Decode<'de, M, A> for $ty<T $(, $extra)*>
321 where
322 A: Allocator,
323 T: Decode<'de, M, A> $(+ $trait0 $(+ $trait)*)*,
324 $($extra: $extra_bound0 $(+ $extra_bound)*),*
325 {
326 const IS_BITWISE_DECODE: bool = false;
327
328 #[inline]
329 fn decode<D>(decoder: D) -> Result<Self, D::Error>
330 where
331 D: Decoder<'de, Mode = M, Allocator = A>,
332 {
333 let $cx = decoder.cx();
334
335 decoder.decode_sequence(|$access| {
336 let mut out = $factory;
337
338 let mut index = 0;
339
340 while let Some(value) = $access.try_decode_next()? {
341 $cx.enter_sequence_index(index);
342 out.$insert(value.decode()?);
343 $cx.leave_sequence_index();
344 index = index.wrapping_add(1);
345 }
346
347 Ok(out)
348 })
349 }
350 }
351
352 $(#[$($meta)*])*
353 impl<M, T $(, $extra)*> EncodePacked<M> for $ty<T $(, $extra)*>
354 where
355 T: Encode<M>,
356 $($extra: $extra_bound0 $(+ $extra_bound)*),*
357 {
358 #[inline]
359 fn encode_packed<E>(&self, encoder: E) -> Result<(), E::Error>
360 where
361 E: Encoder<Mode = M>,
362 {
363 let $cx = encoder.cx();
364
365 encoder.encode_pack_fn(|pack| {
366 let mut index = 0;
367
368 for value in self {
369 $cx.enter_sequence_index(index);
370 pack.push(value)?;
371 $cx.leave_sequence_index();
372 index = index.wrapping_add(1);
373 }
374
375 Ok(())
376 })
377 }
378 }
379 }
380}
381
382crate::internal::macros::slice_sequence! {
383 cx,
384 Vec<T>,
385 || Vec::new(),
386 |vec, value| vec.push(value),
387 |vec, capacity| vec.reserve(capacity),
388 |size| Vec::with_capacity(size),
389}
390
391impl<M, T> Encode<M> for VecDeque<T>
392where
393 T: Encode<M>,
394{
395 type Encode = Self;
396
397 const IS_BITWISE_ENCODE: bool = false;
398
399 #[inline]
400 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
401 where
402 E: Encoder<Mode = M>,
403 {
404 let (a, b) = self.as_slices();
405 encoder.encode_slices(self.len(), [a, b])
406 }
407
408 #[inline]
409 fn as_encode(&self) -> &Self::Encode {
410 self
411 }
412}
413
414impl<'de, M, A, T> Decode<'de, M, A> for VecDeque<T>
415where
416 A: Allocator,
417 T: Decode<'de, M, A>,
418{
419 const IS_BITWISE_DECODE: bool = false;
420
421 #[inline]
422 fn decode<D>(decoder: D) -> Result<Self, D::Error>
423 where
424 D: Decoder<'de, Mode = M, Allocator = A>,
425 {
426 Ok(VecDeque::from(Vec::decode(decoder)?))
427 }
428}
429
430impl<M, T> EncodePacked<M> for VecDeque<T>
431where
432 T: Encode<M>,
433{
434 #[inline]
435 fn encode_packed<E>(&self, encoder: E) -> Result<(), E::Error>
436 where
437 E: Encoder<Mode = M>,
438 {
439 encoder.encode_pack_fn(|pack| {
440 let (a, b) = self.as_slices();
441 pack.encode_slices([a, b])
442 })
443 }
444}
445
446sequence! {
447 cx,
448 BTreeSet<T: Ord>,
449 insert,
450 seq,
451 BTreeSet::new()
452}
453
454sequence! {
455 #[cfg(feature = "std")]
456 #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
457 cx,
458 HashSet<T: Eq + Hash, S: BuildHasher + Default>,
459 insert,
460 seq,
461 HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default())
462}
463
464sequence! {
465 cx,
466 BinaryHeap<T: Ord>,
467 push,
468 seq,
469 BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint()))
470}
471
472macro_rules! map {
473 (
474 $(#[$($meta:meta)*])*
475 $cx:ident,
476 $ty:ident<K $(: $key_bound0:ident $(+ $key_bound:ident)*)?, V $(, $extra:ident: $extra_bound0:ident $(+ $extra_bound:ident)*)*>,
477 $access:ident,
478 $with_capacity:expr
479 ) => {
480 $(#[$($meta)*])*
481 impl<'de, M, K, V $(, $extra)*> Encode<M> for $ty<K, V $(, $extra)*>
482 where
483 K: Encode<M>,
484 V: Encode<M>,
485 $($extra: $extra_bound0 $(+ $extra_bound)*),*
486 {
487 const IS_BITWISE_ENCODE: bool = false;
488
489 type Encode = Self;
490
491 #[inline]
492 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
493 where
494 E: Encoder<Mode = M>,
495 {
496 let hint = self.len();
497
498 encoder.encode_map_fn(hint, |map| {
499 for (k, v) in self {
500 map.insert_entry(k, v)?;
501 }
502
503 Ok(())
504 })
505 }
506
507 #[inline]
508 fn as_encode(&self) -> &Self::Encode {
509 self
510 }
511 }
512
513 $(#[$($meta)*])*
514 impl<'de, M, K, V $(, $extra)*> EncodeTrace<M> for $ty<K, V $(, $extra)*>
515 where
516 K: fmt::Display + Encode<M>,
517 V: Encode<M>,
518 $($extra: $extra_bound0 $(+ $extra_bound)*),*
519 {
520 #[inline]
521 fn trace_encode<E>(&self, encoder: E) -> Result<(), E::Error>
522 where
523 E: Encoder<Mode = M>,
524 {
525 let hint = self.len();
526
527 let $cx = encoder.cx();
528
529 encoder.encode_map_fn(hint, |map| {
530 for (k, v) in self {
531 $cx.enter_map_key(k);
532 map.encode_entry_fn(|entry| {
533 entry.encode_key()?.encode(k)?;
534 entry.encode_value()?.encode(v)?;
535 Ok(())
536 })?;
537 $cx.leave_map_key();
538 }
539
540 Ok(())
541 })
542 }
543 }
544
545 $(#[$($meta)*])*
546 impl<'de, K, V, A, M $(, $extra)*> Decode<'de, M, A> for $ty<K, V $(, $extra)*>
547 where
548 A: Allocator,
549 K: Decode<'de, M, A> $(+ $key_bound0 $(+ $key_bound)*)*,
550 V: Decode<'de, M, A>,
551 $($extra: $extra_bound0 $(+ $extra_bound)*),*
552 {
553 const IS_BITWISE_DECODE: bool = false;
554
555 #[inline]
556 fn decode<D>(decoder: D) -> Result<Self, D::Error>
557 where
558 D: Decoder<'de, Mode = M, Allocator = A>,
559 {
560 decoder.decode_map(|$access| {
561 let mut out = $with_capacity;
562
563 while let Some((key, value)) = $access.entry()? {
564 out.insert(key, value);
565 }
566
567 Ok(out)
568 })
569 }
570 }
571
572 $(#[$($meta)*])*
573 impl<'de, K, V, A, M $(, $extra)*> DecodeTrace<'de, M, A> for $ty<K, V $(, $extra)*>
574 where
575 A: Allocator,
576 K: fmt::Display + Decode<'de, M, A> $(+ $key_bound0 $(+ $key_bound)*)*,
577 V: Decode<'de, M, A>,
578 $($extra: $extra_bound0 $(+ $extra_bound)*),*
579 {
580 #[inline]
581 fn trace_decode<D>(decoder: D) -> Result<Self, D::Error>
582 where
583 D: Decoder<'de, Mode = M, Allocator = A>,
584 {
585 let $cx = decoder.cx();
586
587 decoder.decode_map(|$access| {
588 let mut out = $with_capacity;
589
590 while let Some(mut entry) = $access.decode_entry()? {
591 let key = entry.decode_key()?.decode()?;
592 $cx.enter_map_key(&key);
593 let value = entry.decode_value()?.decode()?;
594 out.insert(key, value);
595 $cx.leave_map_key();
596 }
597
598 Ok(out)
599 })
600 }
601 }
602 }
603}
604
605map!(_cx, BTreeMap<K: Ord, V>, map, BTreeMap::new());
606
607map!(
608 #[cfg(feature = "std")]
609 #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
610 _cx,
611 HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
612 map,
613 HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default())
614);
615
616impl<M> Encode<M> for CString {
617 type Encode = CStr;
618
619 const IS_BITWISE_ENCODE: bool = false;
620
621 #[inline]
622 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
623 where
624 E: Encoder,
625 {
626 encoder.encode_bytes(self.to_bytes_with_nul())
627 }
628
629 #[inline]
630 fn as_encode(&self) -> &Self::Encode {
631 self
632 }
633}
634
635impl<'de, M, A> Decode<'de, M, A> for CString
636where
637 A: Allocator,
638{
639 const IS_BITWISE_DECODE: bool = false;
640
641 #[inline]
642 fn decode<D>(decoder: D) -> Result<Self, D::Error>
643 where
644 D: Decoder<'de, Allocator = A>,
645 {
646 struct Visitor;
647
648 #[crate::de::unsized_visitor(crate)]
649 impl<C> UnsizedVisitor<'_, C, [u8]> for Visitor
650 where
651 C: Context,
652 {
653 type Ok = CString;
654
655 #[inline]
656 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
657 write!(f, "a cstring")
658 }
659
660 #[inline]
661 fn visit_owned(
662 self,
663 cx: C,
664 value: crate::alloc::Vec<u8, Self::Allocator>,
665 ) -> Result<Self::Ok, Self::Error> {
666 match value.into_std() {
667 Ok(value) => CString::from_vec_with_nul(value).map_err(cx.map()),
668 Err(value) => self.visit_ref(cx, &value),
669 }
670 }
671
672 #[inline]
673 fn visit_ref(self, cx: C, bytes: &[u8]) -> Result<Self::Ok, Self::Error> {
674 let value = CStr::from_bytes_with_nul(bytes).map_err(cx.map())?;
675 Ok(rust_alloc::borrow::ToOwned::to_owned(value))
676 }
677 }
678
679 decoder.decode_bytes(Visitor)
680 }
681}
682
683macro_rules! smart_pointer {
684 ($($ty:ident),* $(,)?) => {
685 $(
686 impl<M, T> Encode<M> for $ty<T>
687 where
688 T: ?Sized + Encode<M>,
689 {
690 const IS_BITWISE_ENCODE: bool = false;
691
692 type Encode = T;
693
694 #[inline]
695 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
696 where
697 E: Encoder<Mode = M>,
698 {
699 self.as_ref().encode(encoder)
700 }
701
702 #[inline]
703 fn as_encode(&self) -> &Self::Encode {
704 self
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::new(decoder.decode()?))
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}