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