platform_serialization/features/
impl_alloc.rs

1use crate::{
2    impl_platform_versioned_borrow_decode, PlatformVersionEncode, PlatformVersionedBorrowDecode,
3    PlatformVersionedDecode,
4};
5#[cfg(target_has_atomic = "ptr")]
6use alloc::sync::Arc;
7use alloc::{
8    borrow::{Cow, ToOwned},
9    boxed::Box,
10    collections::*,
11    rc::Rc,
12    string::String,
13    vec::Vec,
14};
15use bincode::config::Config;
16use bincode::de::read::Reader;
17use bincode::de::{BorrowDecoder, Decoder};
18use bincode::enc::write::{SizeWriter, Writer};
19use bincode::enc::Encoder;
20use bincode::error::{DecodeError, EncodeError};
21use bincode::{enc, Encode};
22use platform_version::version::PlatformVersion;
23
24#[derive(Default)]
25pub(crate) struct VecWriter {
26    inner: Vec<u8>,
27}
28
29impl VecWriter {
30    /// Create a new vec writer with the given capacity
31    pub fn with_capacity(cap: usize) -> Self {
32        Self {
33            inner: Vec::with_capacity(cap),
34        }
35    }
36    // May not be used in all feature combinations
37    #[allow(dead_code)]
38    pub(crate) fn collect(self) -> Vec<u8> {
39        self.inner
40    }
41}
42
43impl bincode::enc::write::Writer for VecWriter {
44    #[inline(always)]
45    fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
46        self.inner.extend_from_slice(bytes);
47        Ok(())
48    }
49}
50
51/// PlatformVersionEncode the given value into a `Vec<u8>` with the given `Config`. See the [config] module for more information.
52///
53/// [config]: config/index.html
54#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
55pub fn platform_encode_to_vec<E: PlatformVersionEncode, C: Config>(
56    val: E,
57    config: C,
58    platform_version: &PlatformVersion,
59) -> Result<Vec<u8>, EncodeError> {
60    let size = {
61        let mut size_writer = enc::EncoderImpl::<_, C>::new(SizeWriter::default(), config);
62        val.platform_encode(&mut size_writer, platform_version)?;
63        size_writer.into_writer().bytes_written
64    };
65    let writer = VecWriter::with_capacity(size);
66    let mut encoder = enc::EncoderImpl::<_, C>::new(writer, config);
67    val.platform_encode(&mut encoder, platform_version)?;
68    Ok(encoder.into_writer().inner)
69}
70
71impl<T> PlatformVersionedDecode for BinaryHeap<T>
72where
73    T: PlatformVersionedDecode + Ord,
74{
75    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
76        decoder: &mut D,
77        platform_versioned: &PlatformVersion,
78    ) -> Result<Self, DecodeError> {
79        let len = crate::de::decode_slice_len(decoder)?;
80        decoder.claim_container_read::<T>(len)?;
81
82        let mut map = BinaryHeap::with_capacity(len);
83        for _ in 0..len {
84            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
85            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
86
87            let key = T::platform_versioned_decode(decoder, platform_versioned)?;
88            map.push(key);
89        }
90        Ok(map)
91    }
92}
93impl<'de, T> PlatformVersionedBorrowDecode<'de> for BinaryHeap<T>
94where
95    T: PlatformVersionedBorrowDecode<'de> + Ord,
96{
97    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
98        decoder: &mut D,
99        platform_versioned: &PlatformVersion,
100    ) -> Result<Self, DecodeError> {
101        let len = crate::de::decode_slice_len(decoder)?;
102        decoder.claim_container_read::<T>(len)?;
103
104        let mut map = BinaryHeap::with_capacity(len);
105        for _ in 0..len {
106            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
107            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
108
109            let key = T::platform_versioned_borrow_decode(decoder, platform_versioned)?;
110            map.push(key);
111        }
112        Ok(map)
113    }
114}
115
116impl<T> PlatformVersionEncode for BinaryHeap<T>
117where
118    T: PlatformVersionEncode + Ord,
119{
120    fn platform_encode<E: Encoder>(
121        &self,
122        encoder: &mut E,
123        platform_version: &PlatformVersion,
124    ) -> Result<(), EncodeError> {
125        crate::enc::encode_slice_len(encoder, self.len())?;
126        for val in self.iter() {
127            val.platform_encode(encoder, platform_version)?;
128        }
129        Ok(())
130    }
131}
132
133impl<K, V> PlatformVersionedDecode for BTreeMap<K, V>
134where
135    K: PlatformVersionedDecode + Ord,
136    V: PlatformVersionedDecode,
137{
138    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
139        decoder: &mut D,
140        platform_versioned: &PlatformVersion,
141    ) -> Result<Self, DecodeError> {
142        let len = crate::de::decode_slice_len(decoder)?;
143        decoder.claim_container_read::<(K, V)>(len)?;
144
145        let mut map = BTreeMap::new();
146        for _ in 0..len {
147            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
148            decoder.unclaim_bytes_read(core::mem::size_of::<(K, V)>());
149
150            let key = K::platform_versioned_decode(decoder, platform_versioned)?;
151            let value = V::platform_versioned_decode(decoder, platform_versioned)?;
152            map.insert(key, value);
153        }
154        Ok(map)
155    }
156}
157impl<'de, K, V> PlatformVersionedBorrowDecode<'de> for BTreeMap<K, V>
158where
159    K: PlatformVersionedBorrowDecode<'de> + Ord,
160    V: PlatformVersionedBorrowDecode<'de>,
161{
162    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
163        decoder: &mut D,
164        platform_versioned: &PlatformVersion,
165    ) -> Result<Self, DecodeError> {
166        let len = crate::de::decode_slice_len(decoder)?;
167        decoder.claim_container_read::<(K, V)>(len)?;
168
169        let mut map = BTreeMap::new();
170        for _ in 0..len {
171            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
172            decoder.unclaim_bytes_read(core::mem::size_of::<(K, V)>());
173
174            let key = K::platform_versioned_borrow_decode(decoder, platform_versioned)?;
175            let value = V::platform_versioned_borrow_decode(decoder, platform_versioned)?;
176            map.insert(key, value);
177        }
178        Ok(map)
179    }
180}
181
182impl<K, V> PlatformVersionEncode for BTreeMap<K, V>
183where
184    K: PlatformVersionEncode + Ord,
185    V: PlatformVersionEncode,
186{
187    fn platform_encode<E: Encoder>(
188        &self,
189        encoder: &mut E,
190        platform_version: &PlatformVersion,
191    ) -> Result<(), EncodeError> {
192        crate::enc::encode_slice_len(encoder, self.len())?;
193        for (key, val) in self.iter() {
194            key.platform_encode(encoder, platform_version)?;
195            val.platform_encode(encoder, platform_version)?;
196        }
197        Ok(())
198    }
199}
200
201impl<T> PlatformVersionedDecode for BTreeSet<T>
202where
203    T: PlatformVersionedDecode + Ord,
204{
205    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
206        decoder: &mut D,
207        platform_versioned: &PlatformVersion,
208    ) -> Result<Self, DecodeError> {
209        let len = crate::de::decode_slice_len(decoder)?;
210        decoder.claim_container_read::<T>(len)?;
211
212        let mut map = BTreeSet::new();
213        for _ in 0..len {
214            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
215            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
216
217            let key = T::platform_versioned_decode(decoder, platform_versioned)?;
218            map.insert(key);
219        }
220        Ok(map)
221    }
222}
223impl<'de, T> PlatformVersionedBorrowDecode<'de> for BTreeSet<T>
224where
225    T: PlatformVersionedBorrowDecode<'de> + Ord,
226{
227    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
228        decoder: &mut D,
229        platform_versioned: &PlatformVersion,
230    ) -> Result<Self, DecodeError> {
231        let len = crate::de::decode_slice_len(decoder)?;
232        decoder.claim_container_read::<T>(len)?;
233
234        let mut map = BTreeSet::new();
235        for _ in 0..len {
236            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
237            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
238
239            let key = T::platform_versioned_borrow_decode(decoder, platform_versioned)?;
240            map.insert(key);
241        }
242        Ok(map)
243    }
244}
245
246impl<T> PlatformVersionEncode for BTreeSet<T>
247where
248    T: PlatformVersionEncode + Ord,
249{
250    fn platform_encode<E: Encoder>(
251        &self,
252        encoder: &mut E,
253        platform_version: &PlatformVersion,
254    ) -> Result<(), EncodeError> {
255        crate::enc::encode_slice_len(encoder, self.len())?;
256        for item in self.iter() {
257            item.platform_encode(encoder, platform_version)?;
258        }
259        Ok(())
260    }
261}
262
263impl<T> PlatformVersionedDecode for VecDeque<T>
264where
265    T: PlatformVersionedDecode,
266{
267    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
268        decoder: &mut D,
269        platform_versioned: &PlatformVersion,
270    ) -> Result<Self, DecodeError> {
271        let len = crate::de::decode_slice_len(decoder)?;
272        decoder.claim_container_read::<T>(len)?;
273
274        let mut map = VecDeque::with_capacity(len);
275        for _ in 0..len {
276            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
277            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
278
279            let key = T::platform_versioned_decode(decoder, platform_versioned)?;
280            map.push_back(key);
281        }
282        Ok(map)
283    }
284}
285impl<'de, T> PlatformVersionedBorrowDecode<'de> for VecDeque<T>
286where
287    T: PlatformVersionedBorrowDecode<'de>,
288{
289    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
290        decoder: &mut D,
291        platform_versioned: &PlatformVersion,
292    ) -> Result<Self, DecodeError> {
293        let len = crate::de::decode_slice_len(decoder)?;
294        decoder.claim_container_read::<T>(len)?;
295
296        let mut map = VecDeque::with_capacity(len);
297        for _ in 0..len {
298            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
299            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
300
301            let key = T::platform_versioned_borrow_decode(decoder, platform_versioned)?;
302            map.push_back(key);
303        }
304        Ok(map)
305    }
306}
307
308impl<T> PlatformVersionEncode for VecDeque<T>
309where
310    T: PlatformVersionEncode,
311{
312    fn platform_encode<E: Encoder>(
313        &self,
314        encoder: &mut E,
315        platform_version: &PlatformVersion,
316    ) -> Result<(), EncodeError> {
317        crate::enc::encode_slice_len(encoder, self.len())?;
318        for item in self.iter() {
319            item.platform_encode(encoder, platform_version)?;
320        }
321        Ok(())
322    }
323}
324
325impl<T> PlatformVersionedDecode for Vec<T>
326where
327    T: PlatformVersionedDecode + 'static,
328{
329    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
330        decoder: &mut D,
331        platform_version: &PlatformVersion,
332    ) -> Result<Self, DecodeError> {
333        let len = crate::de::decode_slice_len(decoder)?;
334
335        if core::any::TypeId::of::<T>() == core::any::TypeId::of::<u8>() {
336            decoder.claim_container_read::<T>(len)?;
337            // optimize for reading u8 vecs
338            let mut vec = vec![0u8; len];
339            decoder.reader().read(&mut vec)?;
340            // Safety: Vec<T> is Vec<u8>
341            return Ok(unsafe { core::mem::transmute::<Vec<u8>, Vec<T>>(vec) });
342        }
343        decoder.claim_container_read::<T>(len)?;
344
345        let mut vec = Vec::with_capacity(len);
346        for _ in 0..len {
347            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
348            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
349
350            vec.push(T::platform_versioned_decode(decoder, platform_version)?);
351        }
352        Ok(vec)
353    }
354}
355
356impl<'de, T> PlatformVersionedBorrowDecode<'de> for Vec<T>
357where
358    T: PlatformVersionedBorrowDecode<'de>,
359{
360    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
361        decoder: &mut D,
362        platform_version: &PlatformVersion,
363    ) -> Result<Self, DecodeError> {
364        let len = crate::de::decode_slice_len(decoder)?;
365        decoder.claim_container_read::<T>(len)?;
366
367        let mut vec = Vec::with_capacity(len);
368        for _ in 0..len {
369            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
370            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
371
372            vec.push(T::platform_versioned_borrow_decode(
373                decoder,
374                platform_version,
375            )?);
376        }
377        Ok(vec)
378    }
379}
380
381impl<T> PlatformVersionEncode for Vec<T>
382where
383    T: PlatformVersionEncode + 'static,
384{
385    fn platform_encode<E: Encoder>(
386        &self,
387        encoder: &mut E,
388        platform_version: &PlatformVersion,
389    ) -> Result<(), EncodeError> {
390        crate::enc::encode_slice_len(encoder, self.len())?;
391        if core::any::TypeId::of::<T>() == core::any::TypeId::of::<u8>() {
392            let slice: &[u8] = unsafe { core::mem::transmute(self.as_slice()) };
393            encoder.writer().write(slice)?;
394            return Ok(());
395        }
396        for item in self.iter() {
397            item.platform_encode(encoder, platform_version)?;
398        }
399        Ok(())
400    }
401}
402
403impl PlatformVersionedDecode for String {
404    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
405        decoder: &mut D,
406        _: &PlatformVersion,
407    ) -> Result<Self, DecodeError> {
408        bincode::Decode::decode(decoder)
409    }
410}
411impl_platform_versioned_borrow_decode!(String);
412
413impl PlatformVersionedDecode for Box<str> {
414    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
415        decoder: &mut D,
416        _: &PlatformVersion,
417    ) -> Result<Self, DecodeError> {
418        bincode::Decode::decode(decoder)
419    }
420}
421impl_platform_versioned_borrow_decode!(Box<str>);
422
423impl PlatformVersionEncode for String {
424    fn platform_encode<E: Encoder>(
425        &self,
426        encoder: &mut E,
427        _: &PlatformVersion,
428    ) -> Result<(), EncodeError> {
429        Encode::encode(self, encoder)
430    }
431}
432
433impl<T> PlatformVersionedDecode for Box<T>
434where
435    T: PlatformVersionedDecode,
436{
437    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
438        decoder: &mut D,
439        platform_versioned: &PlatformVersion,
440    ) -> Result<Self, DecodeError> {
441        let t = T::platform_versioned_decode(decoder, platform_versioned)?;
442        Ok(Box::new(t))
443    }
444}
445impl<'de, T> PlatformVersionedBorrowDecode<'de> for Box<T>
446where
447    T: PlatformVersionedBorrowDecode<'de>,
448{
449    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
450        decoder: &mut D,
451        platform_versioned: &PlatformVersion,
452    ) -> Result<Self, DecodeError> {
453        let t = T::platform_versioned_borrow_decode(decoder, platform_versioned)?;
454        Ok(Box::new(t))
455    }
456}
457
458impl<T> PlatformVersionEncode for Box<T>
459where
460    T: PlatformVersionEncode + ?Sized,
461{
462    fn platform_encode<E: Encoder>(
463        &self,
464        encoder: &mut E,
465        platform_version: &PlatformVersion,
466    ) -> Result<(), EncodeError> {
467        T::platform_encode(self, encoder, platform_version)
468    }
469}
470
471impl<T> PlatformVersionedDecode for Box<[T]>
472where
473    T: PlatformVersionedDecode + 'static,
474{
475    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
476        decoder: &mut D,
477        platform_version: &PlatformVersion,
478    ) -> Result<Self, DecodeError> {
479        let vec = Vec::platform_versioned_decode(decoder, platform_version)?;
480        Ok(vec.into_boxed_slice())
481    }
482}
483
484impl<'de, T> PlatformVersionedBorrowDecode<'de> for Box<[T]>
485where
486    T: PlatformVersionedBorrowDecode<'de> + 'de,
487{
488    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
489        decoder: &mut D,
490        platform_version: &PlatformVersion,
491    ) -> Result<Self, DecodeError> {
492        let vec = Vec::platform_versioned_borrow_decode(decoder, platform_version)?;
493        Ok(vec.into_boxed_slice())
494    }
495}
496
497impl<T> PlatformVersionedDecode for Cow<'_, T>
498where
499    T: ToOwned + ?Sized,
500    <T as ToOwned>::Owned: PlatformVersionedDecode,
501{
502    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
503        decoder: &mut D,
504        platform_versioned: &PlatformVersion,
505    ) -> Result<Self, DecodeError> {
506        let t = <T as ToOwned>::Owned::platform_versioned_decode(decoder, platform_versioned)?;
507        Ok(Cow::Owned(t))
508    }
509}
510impl<'cow, T> PlatformVersionedBorrowDecode<'cow> for Cow<'cow, T>
511where
512    T: ToOwned + ?Sized,
513    &'cow T: PlatformVersionedBorrowDecode<'cow>,
514{
515    fn platform_versioned_borrow_decode<D: BorrowDecoder<'cow, Context = crate::BincodeContext>>(
516        decoder: &mut D,
517        platform_versioned: &PlatformVersion,
518    ) -> Result<Self, DecodeError> {
519        let t = <&T>::platform_versioned_borrow_decode(decoder, platform_versioned)?;
520        Ok(Cow::Borrowed(t))
521    }
522}
523
524impl<T> PlatformVersionEncode for Cow<'_, T>
525where
526    T: ToOwned + ?Sized,
527    for<'a> &'a T: PlatformVersionEncode,
528{
529    fn platform_encode<E: Encoder>(
530        &self,
531        encoder: &mut E,
532        platform_version: &PlatformVersion,
533    ) -> Result<(), EncodeError> {
534        self.as_ref().platform_encode(encoder, platform_version)
535    }
536}
537
538#[test]
539fn test_cow_round_trip() {
540    let start = Cow::Borrowed("Foo");
541    let encoded = crate::platform_encode_to_vec(
542        &start,
543        bincode::config::standard(),
544        PlatformVersion::first(),
545    )
546    .unwrap();
547    let end = crate::platform_versioned_borrow_decode_from_slice::<Cow<str>, _>(
548        &encoded,
549        bincode::config::standard(),
550        PlatformVersion::first(),
551    )
552    .unwrap();
553    assert_eq!(start, end);
554    let end = crate::platform_versioned_decode_from_slice::<Cow<str>, _>(
555        &encoded,
556        bincode::config::standard(),
557        PlatformVersion::first(),
558    )
559    .unwrap();
560    assert_eq!(start, end);
561}
562
563impl<T> PlatformVersionedDecode for Rc<T>
564where
565    T: PlatformVersionedDecode,
566{
567    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
568        decoder: &mut D,
569        platform_version: &PlatformVersion,
570    ) -> Result<Self, DecodeError> {
571        let t = T::platform_versioned_decode(decoder, platform_version)?;
572        Ok(Rc::new(t))
573    }
574}
575
576impl<'de, T> PlatformVersionedBorrowDecode<'de> for Rc<T>
577where
578    T: PlatformVersionedBorrowDecode<'de>,
579{
580    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
581        decoder: &mut D,
582        platform_versioned: &PlatformVersion,
583    ) -> Result<Self, DecodeError> {
584        let t = T::platform_versioned_borrow_decode(decoder, platform_versioned)?;
585        Ok(Rc::new(t))
586    }
587}
588
589impl<T> PlatformVersionEncode for Rc<T>
590where
591    T: PlatformVersionEncode + ?Sized,
592{
593    fn platform_encode<E: Encoder>(
594        &self,
595        encoder: &mut E,
596        platform_version: &PlatformVersion,
597    ) -> Result<(), EncodeError> {
598        T::platform_encode(self, encoder, platform_version)
599    }
600}
601
602impl<T> PlatformVersionedDecode for Rc<[T]>
603where
604    T: PlatformVersionedDecode + 'static,
605{
606    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
607        decoder: &mut D,
608        platform_versioned: &PlatformVersion,
609    ) -> Result<Self, DecodeError> {
610        let vec = Vec::platform_versioned_decode(decoder, platform_versioned)?;
611        Ok(vec.into())
612    }
613}
614
615impl<'de, T> PlatformVersionedBorrowDecode<'de> for Rc<[T]>
616where
617    T: PlatformVersionedBorrowDecode<'de> + 'de,
618{
619    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
620        decoder: &mut D,
621        platform_versioned: &PlatformVersion,
622    ) -> Result<Self, DecodeError> {
623        let vec = Vec::platform_versioned_borrow_decode(decoder, platform_versioned)?;
624        Ok(vec.into())
625    }
626}
627
628#[cfg(target_has_atomic = "ptr")]
629impl<T> PlatformVersionedDecode for Arc<T>
630where
631    T: PlatformVersionedDecode,
632{
633    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
634        decoder: &mut D,
635        platform_version: &PlatformVersion,
636    ) -> Result<Self, DecodeError> {
637        let t = T::platform_versioned_decode(decoder, platform_version)?;
638        Ok(Arc::new(t))
639    }
640}
641
642#[cfg(target_has_atomic = "ptr")]
643impl PlatformVersionedDecode for Arc<str> {
644    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
645        decoder: &mut D,
646        _: &PlatformVersion,
647    ) -> Result<Self, DecodeError> {
648        bincode::Decode::decode(decoder)
649    }
650}
651
652#[cfg(target_has_atomic = "ptr")]
653impl<'de, T> PlatformVersionedBorrowDecode<'de> for Arc<T>
654where
655    T: PlatformVersionedBorrowDecode<'de>,
656{
657    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
658        decoder: &mut D,
659        platform_versioned: &PlatformVersion,
660    ) -> Result<Self, DecodeError> {
661        let t = T::platform_versioned_borrow_decode(decoder, platform_versioned)?;
662        Ok(Arc::new(t))
663    }
664}
665
666#[cfg(target_has_atomic = "ptr")]
667impl<'de> PlatformVersionedBorrowDecode<'de> for Arc<str> {
668    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
669        decoder: &mut D,
670        _: &PlatformVersion,
671    ) -> Result<Self, DecodeError> {
672        bincode::BorrowDecode::borrow_decode(decoder)
673    }
674}
675
676#[cfg(target_has_atomic = "ptr")]
677impl<T> PlatformVersionEncode for Arc<T>
678where
679    T: PlatformVersionEncode + ?Sized,
680{
681    fn platform_encode<E: Encoder>(
682        &self,
683        encoder: &mut E,
684        platform_version: &PlatformVersion,
685    ) -> Result<(), EncodeError> {
686        T::platform_encode(self, encoder, platform_version)
687    }
688}
689
690#[cfg(target_has_atomic = "ptr")]
691impl<T> PlatformVersionedDecode for Arc<[T]>
692where
693    T: PlatformVersionedDecode + 'static,
694{
695    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
696        decoder: &mut D,
697        platform_version: &PlatformVersion,
698    ) -> Result<Self, DecodeError> {
699        let vec = Vec::platform_versioned_decode(decoder, platform_version)?;
700        Ok(vec.into())
701    }
702}
703
704#[cfg(target_has_atomic = "ptr")]
705impl<'de, T> PlatformVersionedBorrowDecode<'de> for Arc<[T]>
706where
707    T: PlatformVersionedBorrowDecode<'de> + 'de,
708{
709    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
710        decoder: &mut D,
711        platform_version: &PlatformVersion,
712    ) -> Result<Self, DecodeError> {
713        let vec = Vec::platform_versioned_borrow_decode(decoder, platform_version)?;
714        Ok(vec.into())
715    }
716}
717
718#[cfg(test)]
719mod tests {
720    use super::*;
721    use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, VecDeque};
722    use bincode::config;
723
724    fn cfg() -> impl bincode::config::Config {
725        config::standard().with_big_endian().with_no_limit()
726    }
727
728    fn pv() -> &'static PlatformVersion {
729        PlatformVersion::first()
730    }
731
732    fn round_trip<T>(value: T) -> T
733    where
734        T: PlatformVersionEncode + crate::PlatformVersionedDecode,
735    {
736        let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
737        crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap()
738    }
739
740    // -----------------------------------------------------------------------
741    // platform_encode_to_vec
742    // -----------------------------------------------------------------------
743
744    #[test]
745    fn encode_to_vec_basic() {
746        let encoded = crate::platform_encode_to_vec(42u32, cfg(), pv()).unwrap();
747        assert!(!encoded.is_empty());
748        let decoded: u32 =
749            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
750        assert_eq!(decoded, 42);
751    }
752
753    // -----------------------------------------------------------------------
754    // Vec<T> encode/decode: u8 optimization vs generic
755    // -----------------------------------------------------------------------
756
757    #[test]
758    fn vec_u8_round_trip() {
759        let value: Vec<u8> = vec![0, 1, 2, 255, 128];
760        assert_eq!(round_trip(value.clone()), value);
761    }
762
763    #[test]
764    fn vec_u32_round_trip() {
765        let value: Vec<u32> = vec![100, 200, 300];
766        assert_eq!(round_trip(value.clone()), value);
767    }
768
769    #[test]
770    fn vec_empty_round_trip() {
771        let value: Vec<u32> = vec![];
772        assert_eq!(round_trip(value.clone()), value);
773    }
774
775    // -----------------------------------------------------------------------
776    // BTreeMap
777    // -----------------------------------------------------------------------
778
779    #[test]
780    fn btree_map_round_trip() {
781        let mut map = BTreeMap::new();
782        map.insert(1u32, "one".to_string());
783        map.insert(2, "two".to_string());
784        map.insert(3, "three".to_string());
785        assert_eq!(round_trip(map.clone()), map);
786    }
787
788    #[test]
789    fn btree_map_empty_round_trip() {
790        let map: BTreeMap<u32, String> = BTreeMap::new();
791        assert_eq!(round_trip(map.clone()), map);
792    }
793
794    // -----------------------------------------------------------------------
795    // BTreeSet
796    // -----------------------------------------------------------------------
797
798    #[test]
799    fn btree_set_round_trip() {
800        let mut set = BTreeSet::new();
801        set.insert(10u32);
802        set.insert(20);
803        set.insert(30);
804        assert_eq!(round_trip(set.clone()), set);
805    }
806
807    // -----------------------------------------------------------------------
808    // BinaryHeap
809    // -----------------------------------------------------------------------
810
811    #[test]
812    fn binary_heap_round_trip() {
813        let mut heap = BinaryHeap::new();
814        heap.push(3u32);
815        heap.push(1);
816        heap.push(2);
817        let result = round_trip(heap);
818        // BinaryHeap doesn't implement Eq, so compare sorted vecs
819        let sorted: Vec<u32> = result.into_sorted_vec();
820        assert_eq!(sorted, vec![1, 2, 3]);
821    }
822
823    // -----------------------------------------------------------------------
824    // VecDeque
825    // -----------------------------------------------------------------------
826
827    #[test]
828    fn vec_deque_round_trip() {
829        let mut deque = VecDeque::new();
830        deque.push_back(1u32);
831        deque.push_back(2);
832        deque.push_front(0);
833        assert_eq!(round_trip(deque.clone()), deque);
834    }
835
836    // -----------------------------------------------------------------------
837    // String
838    // -----------------------------------------------------------------------
839
840    #[test]
841    fn string_round_trip() {
842        let value = "hello world".to_string();
843        assert_eq!(round_trip(value.clone()), value);
844    }
845
846    #[test]
847    fn string_empty_round_trip() {
848        let value = String::new();
849        assert_eq!(round_trip(value.clone()), value);
850    }
851
852    // -----------------------------------------------------------------------
853    // Box<T>, Box<str>, Box<[T]>
854    // -----------------------------------------------------------------------
855
856    #[test]
857    fn box_round_trip() {
858        let value = Box::new(42u32);
859        assert_eq!(round_trip(value.clone()), value);
860    }
861
862    #[test]
863    fn box_str_round_trip() {
864        let value: Box<str> = "boxed string".into();
865        assert_eq!(round_trip(value.clone()), value);
866    }
867
868    #[test]
869    fn box_slice_round_trip() {
870        let value: Box<[u32]> = vec![1, 2, 3].into_boxed_slice();
871        assert_eq!(round_trip(value.clone()), value);
872    }
873
874    // -----------------------------------------------------------------------
875    // Rc<T>, Rc<[T]>
876    // -----------------------------------------------------------------------
877
878    #[test]
879    fn rc_round_trip() {
880        let value = Rc::new(42u32);
881        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
882        let decoded: Rc<u32> =
883            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
884        assert_eq!(*decoded, 42);
885    }
886
887    #[test]
888    fn rc_slice_round_trip() {
889        let value: Rc<[u32]> = vec![1, 2, 3].into();
890        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
891        let decoded: Rc<[u32]> =
892            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
893        assert_eq!(&*decoded, &[1, 2, 3]);
894    }
895
896    // -----------------------------------------------------------------------
897    // Arc<T>, Arc<str>, Arc<[T]>
898    // -----------------------------------------------------------------------
899
900    #[cfg(target_has_atomic = "ptr")]
901    #[test]
902    fn arc_round_trip() {
903        let value = Arc::new(42u32);
904        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
905        let decoded: Arc<u32> =
906            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
907        assert_eq!(*decoded, 42);
908    }
909
910    #[cfg(target_has_atomic = "ptr")]
911    #[test]
912    fn arc_str_round_trip() {
913        let value: Arc<str> = Arc::from("arc string");
914        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
915        let decoded: Arc<str> =
916            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
917        assert_eq!(&*decoded, "arc string");
918    }
919
920    #[cfg(target_has_atomic = "ptr")]
921    #[test]
922    fn arc_slice_round_trip() {
923        let value: Arc<[u32]> = vec![10, 20, 30].into();
924        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
925        let decoded: Arc<[u32]> =
926            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
927        assert_eq!(&*decoded, &[10, 20, 30]);
928    }
929
930    // -----------------------------------------------------------------------
931    // Cow
932    // -----------------------------------------------------------------------
933
934    #[test]
935    fn cow_owned_round_trip() {
936        let value: Cow<str> = Cow::Owned("owned".to_string());
937        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
938        let decoded: Cow<str> =
939            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
940        assert_eq!(decoded, "owned");
941    }
942
943    // -----------------------------------------------------------------------
944    // VecWriter (alloc version)
945    // -----------------------------------------------------------------------
946
947    #[test]
948    fn vec_writer_with_capacity() {
949        let writer = VecWriter::with_capacity(100);
950        let collected = writer.collect();
951        assert!(collected.is_empty());
952        assert!(collected.capacity() >= 100);
953    }
954
955    // -----------------------------------------------------------------------
956    // Borrow-decode paths for collection types
957    // -----------------------------------------------------------------------
958
959    #[test]
960    fn btree_map_borrow_decode() {
961        let mut map = BTreeMap::new();
962        map.insert(1u32, 10u32);
963        map.insert(2, 20);
964        let encoded = crate::platform_encode_to_vec(&map, cfg(), pv()).unwrap();
965        let decoded: BTreeMap<u32, u32> =
966            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
967        assert_eq!(decoded, map);
968    }
969
970    #[test]
971    fn btree_set_borrow_decode() {
972        let mut set = BTreeSet::new();
973        set.insert(1u32);
974        set.insert(2);
975        let encoded = crate::platform_encode_to_vec(&set, cfg(), pv()).unwrap();
976        let decoded: BTreeSet<u32> =
977            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
978        assert_eq!(decoded, set);
979    }
980
981    #[test]
982    fn binary_heap_borrow_decode() {
983        let mut heap = BinaryHeap::new();
984        heap.push(5u32);
985        heap.push(3);
986        heap.push(7);
987        let encoded = crate::platform_encode_to_vec(&heap, cfg(), pv()).unwrap();
988        let decoded: BinaryHeap<u32> =
989            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
990        let sorted: Vec<u32> = decoded.into_sorted_vec();
991        assert_eq!(sorted, vec![3, 5, 7]);
992    }
993
994    #[test]
995    fn vec_deque_borrow_decode() {
996        let mut deque = VecDeque::new();
997        deque.push_back(1u32);
998        deque.push_back(2);
999        let encoded = crate::platform_encode_to_vec(&deque, cfg(), pv()).unwrap();
1000        let decoded: VecDeque<u32> =
1001            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1002        assert_eq!(decoded, deque);
1003    }
1004
1005    #[test]
1006    fn vec_borrow_decode() {
1007        let value: Vec<u32> = vec![1, 2, 3];
1008        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1009        let decoded: Vec<u32> =
1010            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1011        assert_eq!(decoded, value);
1012    }
1013
1014    #[test]
1015    fn box_borrow_decode() {
1016        let value = Box::new(42u32);
1017        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1018        let decoded: Box<u32> =
1019            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1020        assert_eq!(decoded, value);
1021    }
1022
1023    #[test]
1024    fn box_slice_borrow_decode() {
1025        let value: Box<[u32]> = vec![10, 20, 30].into_boxed_slice();
1026        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1027        let decoded: Box<[u32]> =
1028            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1029        assert_eq!(decoded, value);
1030    }
1031
1032    #[test]
1033    fn rc_borrow_decode() {
1034        let value = Rc::new(42u32);
1035        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1036        let decoded: Rc<u32> =
1037            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1038        assert_eq!(*decoded, 42);
1039    }
1040
1041    #[test]
1042    fn rc_slice_borrow_decode() {
1043        let value: Rc<[u32]> = vec![1, 2, 3].into();
1044        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1045        let decoded: Rc<[u32]> =
1046            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1047        assert_eq!(&*decoded, &[1, 2, 3]);
1048    }
1049
1050    #[cfg(target_has_atomic = "ptr")]
1051    #[test]
1052    fn arc_borrow_decode() {
1053        let value = Arc::new(42u32);
1054        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1055        let decoded: Arc<u32> =
1056            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1057        assert_eq!(*decoded, 42);
1058    }
1059
1060    #[cfg(target_has_atomic = "ptr")]
1061    #[test]
1062    fn arc_str_borrow_decode() {
1063        let value: Arc<str> = Arc::from("test arc str");
1064        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1065        let decoded: Arc<str> =
1066            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1067        assert_eq!(&*decoded, "test arc str");
1068    }
1069
1070    #[cfg(target_has_atomic = "ptr")]
1071    #[test]
1072    fn arc_slice_borrow_decode() {
1073        let value: Arc<[u32]> = vec![10, 20].into();
1074        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1075        let decoded: Arc<[u32]> =
1076            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1077        assert_eq!(&*decoded, &[10, 20]);
1078    }
1079
1080    #[test]
1081    fn cow_borrow_decode() {
1082        use alloc::borrow::Cow;
1083        let value = "borrowed cow";
1084        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1085        let decoded: Cow<str> =
1086            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1087        assert_eq!(&*decoded, value);
1088    }
1089}