musli_core/impls/
alloc.rs

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                // SAFETY: We've just resized the above buffer.
875                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            // SAFETY: Slice does not outlive the buffer it references.
885            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}