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