Skip to main content

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)]
719#[allow(clippy::needless_borrows_for_generic_args)]
720mod tests {
721    use super::*;
722    use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, VecDeque};
723    use bincode::config;
724
725    fn cfg() -> impl bincode::config::Config {
726        config::standard().with_big_endian().with_no_limit()
727    }
728
729    fn pv() -> &'static PlatformVersion {
730        PlatformVersion::first()
731    }
732
733    fn round_trip<T>(value: T) -> T
734    where
735        T: PlatformVersionEncode + crate::PlatformVersionedDecode,
736    {
737        let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
738        crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap()
739    }
740
741    // -----------------------------------------------------------------------
742    // platform_encode_to_vec
743    // -----------------------------------------------------------------------
744
745    #[test]
746    fn encode_to_vec_basic() {
747        let encoded = crate::platform_encode_to_vec(42u32, cfg(), pv()).unwrap();
748        assert!(!encoded.is_empty());
749        let decoded: u32 =
750            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
751        assert_eq!(decoded, 42);
752    }
753
754    // -----------------------------------------------------------------------
755    // Vec<T> encode/decode: u8 optimization vs generic
756    // -----------------------------------------------------------------------
757
758    #[test]
759    fn vec_u8_round_trip() {
760        let value: Vec<u8> = vec![0, 1, 2, 255, 128];
761        assert_eq!(round_trip(value.clone()), value);
762    }
763
764    #[test]
765    fn vec_u32_round_trip() {
766        let value: Vec<u32> = vec![100, 200, 300];
767        assert_eq!(round_trip(value.clone()), value);
768    }
769
770    #[test]
771    fn vec_empty_round_trip() {
772        let value: Vec<u32> = vec![];
773        assert_eq!(round_trip(value.clone()), value);
774    }
775
776    // -----------------------------------------------------------------------
777    // BTreeMap
778    // -----------------------------------------------------------------------
779
780    #[test]
781    fn btree_map_round_trip() {
782        let mut map = BTreeMap::new();
783        map.insert(1u32, "one".to_string());
784        map.insert(2, "two".to_string());
785        map.insert(3, "three".to_string());
786        assert_eq!(round_trip(map.clone()), map);
787    }
788
789    #[test]
790    fn btree_map_empty_round_trip() {
791        let map: BTreeMap<u32, String> = BTreeMap::new();
792        assert_eq!(round_trip(map.clone()), map);
793    }
794
795    // -----------------------------------------------------------------------
796    // BTreeSet
797    // -----------------------------------------------------------------------
798
799    #[test]
800    fn btree_set_round_trip() {
801        let mut set = BTreeSet::new();
802        set.insert(10u32);
803        set.insert(20);
804        set.insert(30);
805        assert_eq!(round_trip(set.clone()), set);
806    }
807
808    // -----------------------------------------------------------------------
809    // BinaryHeap
810    // -----------------------------------------------------------------------
811
812    #[test]
813    fn binary_heap_round_trip() {
814        let mut heap = BinaryHeap::new();
815        heap.push(3u32);
816        heap.push(1);
817        heap.push(2);
818        let result = round_trip(heap);
819        // BinaryHeap doesn't implement Eq, so compare sorted vecs
820        let sorted: Vec<u32> = result.into_sorted_vec();
821        assert_eq!(sorted, vec![1, 2, 3]);
822    }
823
824    // -----------------------------------------------------------------------
825    // VecDeque
826    // -----------------------------------------------------------------------
827
828    #[test]
829    fn vec_deque_round_trip() {
830        let mut deque = VecDeque::new();
831        deque.push_back(1u32);
832        deque.push_back(2);
833        deque.push_front(0);
834        assert_eq!(round_trip(deque.clone()), deque);
835    }
836
837    // -----------------------------------------------------------------------
838    // String
839    // -----------------------------------------------------------------------
840
841    #[test]
842    fn string_round_trip() {
843        let value = "hello world".to_string();
844        assert_eq!(round_trip(value.clone()), value);
845    }
846
847    #[test]
848    fn string_empty_round_trip() {
849        let value = String::new();
850        assert_eq!(round_trip(value.clone()), value);
851    }
852
853    // -----------------------------------------------------------------------
854    // Box<T>, Box<str>, Box<[T]>
855    // -----------------------------------------------------------------------
856
857    #[test]
858    fn box_round_trip() {
859        let value = Box::new(42u32);
860        assert_eq!(round_trip(value.clone()), value);
861    }
862
863    #[test]
864    fn box_str_round_trip() {
865        let value: Box<str> = "boxed string".into();
866        assert_eq!(round_trip(value.clone()), value);
867    }
868
869    #[test]
870    fn box_slice_round_trip() {
871        let value: Box<[u32]> = vec![1, 2, 3].into_boxed_slice();
872        assert_eq!(round_trip(value.clone()), value);
873    }
874
875    // -----------------------------------------------------------------------
876    // Rc<T>, Rc<[T]>
877    // -----------------------------------------------------------------------
878
879    #[test]
880    fn rc_round_trip() {
881        let value = Rc::new(42u32);
882        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
883        let decoded: Rc<u32> =
884            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
885        assert_eq!(*decoded, 42);
886    }
887
888    #[test]
889    fn rc_slice_round_trip() {
890        let value: Rc<[u32]> = vec![1, 2, 3].into();
891        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
892        let decoded: Rc<[u32]> =
893            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
894        assert_eq!(&*decoded, &[1, 2, 3]);
895    }
896
897    // -----------------------------------------------------------------------
898    // Arc<T>, Arc<str>, Arc<[T]>
899    // -----------------------------------------------------------------------
900
901    #[cfg(target_has_atomic = "ptr")]
902    #[test]
903    fn arc_round_trip() {
904        let value = Arc::new(42u32);
905        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
906        let decoded: Arc<u32> =
907            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
908        assert_eq!(*decoded, 42);
909    }
910
911    #[cfg(target_has_atomic = "ptr")]
912    #[test]
913    fn arc_str_round_trip() {
914        let value: Arc<str> = Arc::from("arc string");
915        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
916        let decoded: Arc<str> =
917            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
918        assert_eq!(&*decoded, "arc string");
919    }
920
921    #[cfg(target_has_atomic = "ptr")]
922    #[test]
923    fn arc_slice_round_trip() {
924        let value: Arc<[u32]> = vec![10, 20, 30].into();
925        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
926        let decoded: Arc<[u32]> =
927            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
928        assert_eq!(&*decoded, &[10, 20, 30]);
929    }
930
931    // -----------------------------------------------------------------------
932    // Cow
933    // -----------------------------------------------------------------------
934
935    #[test]
936    fn cow_owned_round_trip() {
937        let value: Cow<str> = Cow::Owned("owned".to_string());
938        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
939        let decoded: Cow<str> =
940            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
941        assert_eq!(decoded, "owned");
942    }
943
944    // -----------------------------------------------------------------------
945    // VecWriter (alloc version)
946    // -----------------------------------------------------------------------
947
948    #[test]
949    fn vec_writer_with_capacity() {
950        let writer = VecWriter::with_capacity(100);
951        let collected = writer.collect();
952        assert!(collected.is_empty());
953        assert!(collected.capacity() >= 100);
954    }
955
956    // -----------------------------------------------------------------------
957    // Borrow-decode paths for collection types
958    // -----------------------------------------------------------------------
959
960    #[test]
961    fn btree_map_borrow_decode() {
962        let mut map = BTreeMap::new();
963        map.insert(1u32, 10u32);
964        map.insert(2, 20);
965        let encoded = crate::platform_encode_to_vec(&map, cfg(), pv()).unwrap();
966        let decoded: BTreeMap<u32, u32> =
967            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
968        assert_eq!(decoded, map);
969    }
970
971    #[test]
972    fn btree_set_borrow_decode() {
973        let mut set = BTreeSet::new();
974        set.insert(1u32);
975        set.insert(2);
976        let encoded = crate::platform_encode_to_vec(&set, cfg(), pv()).unwrap();
977        let decoded: BTreeSet<u32> =
978            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
979        assert_eq!(decoded, set);
980    }
981
982    #[test]
983    fn binary_heap_borrow_decode() {
984        let mut heap = BinaryHeap::new();
985        heap.push(5u32);
986        heap.push(3);
987        heap.push(7);
988        let encoded = crate::platform_encode_to_vec(&heap, cfg(), pv()).unwrap();
989        let decoded: BinaryHeap<u32> =
990            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
991        let sorted: Vec<u32> = decoded.into_sorted_vec();
992        assert_eq!(sorted, vec![3, 5, 7]);
993    }
994
995    #[test]
996    fn vec_deque_borrow_decode() {
997        let mut deque = VecDeque::new();
998        deque.push_back(1u32);
999        deque.push_back(2);
1000        let encoded = crate::platform_encode_to_vec(&deque, cfg(), pv()).unwrap();
1001        let decoded: VecDeque<u32> =
1002            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1003        assert_eq!(decoded, deque);
1004    }
1005
1006    #[test]
1007    fn vec_borrow_decode() {
1008        let value: Vec<u32> = vec![1, 2, 3];
1009        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1010        let decoded: Vec<u32> =
1011            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1012        assert_eq!(decoded, value);
1013    }
1014
1015    #[test]
1016    fn box_borrow_decode() {
1017        let value = Box::new(42u32);
1018        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1019        let decoded: Box<u32> =
1020            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1021        assert_eq!(decoded, value);
1022    }
1023
1024    #[test]
1025    fn box_slice_borrow_decode() {
1026        let value: Box<[u32]> = vec![10, 20, 30].into_boxed_slice();
1027        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1028        let decoded: Box<[u32]> =
1029            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1030        assert_eq!(decoded, value);
1031    }
1032
1033    #[test]
1034    fn rc_borrow_decode() {
1035        let value = Rc::new(42u32);
1036        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1037        let decoded: Rc<u32> =
1038            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1039        assert_eq!(*decoded, 42);
1040    }
1041
1042    #[test]
1043    fn rc_slice_borrow_decode() {
1044        let value: Rc<[u32]> = vec![1, 2, 3].into();
1045        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1046        let decoded: Rc<[u32]> =
1047            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1048        assert_eq!(&*decoded, &[1, 2, 3]);
1049    }
1050
1051    #[cfg(target_has_atomic = "ptr")]
1052    #[test]
1053    fn arc_borrow_decode() {
1054        let value = Arc::new(42u32);
1055        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1056        let decoded: Arc<u32> =
1057            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1058        assert_eq!(*decoded, 42);
1059    }
1060
1061    #[cfg(target_has_atomic = "ptr")]
1062    #[test]
1063    fn arc_str_borrow_decode() {
1064        let value: Arc<str> = Arc::from("test arc str");
1065        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1066        let decoded: Arc<str> =
1067            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1068        assert_eq!(&*decoded, "test arc str");
1069    }
1070
1071    #[cfg(target_has_atomic = "ptr")]
1072    #[test]
1073    fn arc_slice_borrow_decode() {
1074        let value: Arc<[u32]> = vec![10, 20].into();
1075        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1076        let decoded: Arc<[u32]> =
1077            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1078        assert_eq!(&*decoded, &[10, 20]);
1079    }
1080
1081    #[test]
1082    fn cow_borrow_decode() {
1083        use alloc::borrow::Cow;
1084        let value = "borrowed cow";
1085        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
1086        let decoded: Cow<str> =
1087            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
1088        assert_eq!(&*decoded, value);
1089    }
1090}