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