Skip to main content

platform_serialization/features/
impl_std.rs

1use crate::{
2    impl_platform_versioned_borrow_decode, PlatformVersionEncode, PlatformVersionedBorrowDecode,
3    PlatformVersionedDecode,
4};
5use bincode::{
6    config::Config,
7    de::{read::Reader, BorrowDecoder, Decode, Decoder, DecoderImpl},
8    enc::{write::Writer, Encode, Encoder, EncoderImpl},
9    error::{DecodeError, EncodeError},
10};
11
12use platform_version::version::PlatformVersion;
13use std::{
14    collections::{HashMap, HashSet},
15    ffi::{CStr, CString},
16    hash::Hash,
17    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
18    path::{Path, PathBuf},
19    sync::{Mutex, RwLock},
20    time::SystemTime,
21};
22
23/// Decode type `D` from the given reader with the given `Config`. The reader can be any type that implements `std::io::Read`, e.g. `std::fs::File`.
24///
25/// See the [config] module for more information about config options.
26///
27/// [config]: config/index.html
28#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
29#[allow(dead_code)]
30#[deprecated(note = "This function is marked as unused.")]
31#[allow(deprecated)]
32pub fn platform_versioned_decode_from_std_read<
33    D: Decode<crate::BincodeContext>,
34    C: Config,
35    R: std::io::Read,
36>(
37    src: &mut R,
38    config: C,
39) -> Result<D, DecodeError> {
40    let reader = IoReader::new(src);
41    let mut decoder = DecoderImpl::<_, C, crate::BincodeContext>::new(reader, config, ());
42    D::decode(&mut decoder)
43}
44
45pub(crate) struct IoReader<R> {
46    reader: R,
47}
48
49impl<R> IoReader<R> {
50    #[allow(dead_code)]
51    #[deprecated(note = "This function is marked as unused.")]
52    #[allow(deprecated)]
53    pub fn new(reader: R) -> Self {
54        Self { reader }
55    }
56}
57
58impl<R> Reader for IoReader<R>
59where
60    R: std::io::Read,
61{
62    #[inline(always)]
63    fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> {
64        self.reader
65            .read_exact(bytes)
66            .map_err(|inner| DecodeError::Io {
67                inner,
68                additional: bytes.len(),
69            })
70    }
71}
72
73/// Encode the given value into any type that implements `std::io::Write`, e.g. `std::fs::File`, with the given `Config`.
74/// See the [config] module for more information.
75/// Returns the amount of bytes written.
76///
77/// [config]: config/index.html
78#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
79#[allow(dead_code)]
80#[deprecated(note = "This function is marked as unused.")]
81#[allow(deprecated)]
82pub fn encode_into_std_write<E: Encode, C: Config, W: std::io::Write>(
83    val: E,
84    dst: &mut W,
85    config: C,
86) -> Result<usize, EncodeError> {
87    let writer = IoWriter::new(dst);
88    let mut encoder = EncoderImpl::<_, C>::new(writer, config);
89    val.encode(&mut encoder)?;
90    Ok(encoder.into_writer().bytes_written())
91}
92
93pub(crate) struct IoWriter<'a, W: std::io::Write> {
94    writer: &'a mut W,
95    bytes_written: usize,
96}
97
98impl<'a, W: std::io::Write> IoWriter<'a, W> {
99    #[allow(dead_code)]
100    #[deprecated(note = "This function is marked as unused.")]
101    #[allow(deprecated)]
102    pub fn new(writer: &'a mut W) -> Self {
103        Self {
104            writer,
105            bytes_written: 0,
106        }
107    }
108    #[allow(dead_code)]
109    #[deprecated(note = "This function is marked as unused.")]
110    #[allow(deprecated)]
111    pub fn bytes_written(&self) -> usize {
112        self.bytes_written
113    }
114}
115
116impl<W: std::io::Write> Writer for IoWriter<'_, W> {
117    #[inline(always)]
118    fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
119        self.writer
120            .write_all(bytes)
121            .map_err(|inner| EncodeError::Io {
122                inner,
123                index: self.bytes_written,
124            })?;
125        self.bytes_written += bytes.len();
126        Ok(())
127    }
128}
129
130impl PlatformVersionEncode for &CStr {
131    fn platform_encode<E: Encoder>(
132        &self,
133        encoder: &mut E,
134        _: &PlatformVersion,
135    ) -> Result<(), EncodeError> {
136        self.to_bytes().encode(encoder)
137    }
138}
139
140impl PlatformVersionEncode for CString {
141    fn platform_encode<E: Encoder>(
142        &self,
143        encoder: &mut E,
144        _: &PlatformVersion,
145    ) -> Result<(), EncodeError> {
146        self.as_bytes().encode(encoder)
147    }
148}
149
150impl PlatformVersionedDecode for CString {
151    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
152        decoder: &mut D,
153        _: &PlatformVersion,
154    ) -> Result<Self, DecodeError> {
155        bincode::Decode::decode(decoder)
156    }
157}
158impl_platform_versioned_borrow_decode!(CString);
159
160impl<T> PlatformVersionEncode for Mutex<T>
161where
162    T: PlatformVersionEncode,
163{
164    fn platform_encode<E: Encoder>(
165        &self,
166        encoder: &mut E,
167        platform_version: &PlatformVersion,
168    ) -> Result<(), EncodeError> {
169        let t = self.lock().map_err(|_| EncodeError::LockFailed {
170            type_name: core::any::type_name::<Mutex<T>>(),
171        })?;
172        t.platform_encode(encoder, platform_version)
173    }
174}
175
176impl<T> PlatformVersionedDecode for Mutex<T>
177where
178    T: PlatformVersionedDecode,
179{
180    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
181        decoder: &mut D,
182        platform_version: &PlatformVersion,
183    ) -> Result<Self, DecodeError> {
184        let t = T::platform_versioned_decode(decoder, platform_version)?;
185        Ok(Mutex::new(t))
186    }
187}
188impl<'de, T> PlatformVersionedBorrowDecode<'de> for Mutex<T>
189where
190    T: PlatformVersionedBorrowDecode<'de>,
191{
192    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
193        decoder: &mut D,
194        platform_version: &PlatformVersion,
195    ) -> Result<Self, DecodeError> {
196        let t = T::platform_versioned_borrow_decode(decoder, platform_version)?;
197        Ok(Mutex::new(t))
198    }
199}
200
201impl<T> PlatformVersionEncode for RwLock<T>
202where
203    T: PlatformVersionEncode,
204{
205    fn platform_encode<E: Encoder>(
206        &self,
207        encoder: &mut E,
208        platform_version: &PlatformVersion,
209    ) -> Result<(), EncodeError> {
210        let t = self.read().map_err(|_| EncodeError::LockFailed {
211            type_name: core::any::type_name::<RwLock<T>>(),
212        })?;
213        t.platform_encode(encoder, platform_version)
214    }
215}
216
217impl<T> PlatformVersionedDecode for RwLock<T>
218where
219    T: PlatformVersionedDecode,
220{
221    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
222        decoder: &mut D,
223        platform_version: &PlatformVersion,
224    ) -> Result<Self, DecodeError> {
225        let t = T::platform_versioned_decode(decoder, platform_version)?;
226        Ok(RwLock::new(t))
227    }
228}
229impl<'de, T> PlatformVersionedBorrowDecode<'de> for RwLock<T>
230where
231    T: PlatformVersionedBorrowDecode<'de>,
232{
233    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
234        decoder: &mut D,
235        platform_version: &PlatformVersion,
236    ) -> Result<Self, DecodeError> {
237        let t = T::platform_versioned_borrow_decode(decoder, platform_version)?;
238        Ok(RwLock::new(t))
239    }
240}
241
242impl PlatformVersionEncode for SystemTime {
243    fn platform_encode<E: Encoder>(
244        &self,
245        encoder: &mut E,
246        _: &PlatformVersion,
247    ) -> Result<(), EncodeError> {
248        bincode::Encode::encode(self, encoder)
249    }
250}
251
252impl PlatformVersionedDecode for SystemTime {
253    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
254        decoder: &mut D,
255        _: &PlatformVersion,
256    ) -> Result<Self, DecodeError> {
257        bincode::Decode::decode(decoder)
258    }
259}
260impl_platform_versioned_borrow_decode!(SystemTime);
261
262impl PlatformVersionEncode for &'_ Path {
263    fn platform_encode<E: Encoder>(
264        &self,
265        encoder: &mut E,
266        _: &PlatformVersion,
267    ) -> Result<(), EncodeError> {
268        bincode::Encode::encode(self, encoder)
269    }
270}
271
272impl<'de> PlatformVersionedBorrowDecode<'de> for &'de Path {
273    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
274        decoder: &mut D,
275        _: &PlatformVersion,
276    ) -> Result<Self, DecodeError> {
277        bincode::BorrowDecode::borrow_decode(decoder)
278    }
279}
280
281impl PlatformVersionEncode for PathBuf {
282    fn platform_encode<E: Encoder>(
283        &self,
284        encoder: &mut E,
285        _: &PlatformVersion,
286    ) -> Result<(), EncodeError> {
287        bincode::Encode::encode(self, encoder)
288    }
289}
290
291impl PlatformVersionedDecode for PathBuf {
292    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
293        decoder: &mut D,
294        _: &PlatformVersion,
295    ) -> Result<Self, DecodeError> {
296        let _string = std::string::String::decode(decoder)?;
297        bincode::Decode::decode(decoder)
298    }
299}
300impl_platform_versioned_borrow_decode!(PathBuf);
301
302impl PlatformVersionEncode for IpAddr {
303    fn platform_encode<E: Encoder>(
304        &self,
305        encoder: &mut E,
306        _platform_version: &PlatformVersion,
307    ) -> Result<(), EncodeError> {
308        bincode::Encode::encode(self, encoder)
309    }
310}
311
312impl PlatformVersionedDecode for IpAddr {
313    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
314        decoder: &mut D,
315        _platform_version: &PlatformVersion,
316    ) -> Result<Self, DecodeError> {
317        bincode::Decode::decode(decoder)
318    }
319}
320impl_platform_versioned_borrow_decode!(IpAddr);
321
322impl PlatformVersionEncode for Ipv4Addr {
323    fn platform_encode<E: Encoder>(
324        &self,
325        encoder: &mut E,
326        _platform_version: &PlatformVersion,
327    ) -> Result<(), EncodeError> {
328        bincode::Encode::encode(self, encoder)
329    }
330}
331
332impl PlatformVersionedDecode for Ipv4Addr {
333    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
334        decoder: &mut D,
335        _platform_version: &PlatformVersion,
336    ) -> Result<Self, DecodeError> {
337        bincode::Decode::decode(decoder)
338    }
339}
340impl_platform_versioned_borrow_decode!(Ipv4Addr);
341
342impl PlatformVersionEncode for Ipv6Addr {
343    fn platform_encode<E: Encoder>(
344        &self,
345        encoder: &mut E,
346        _: &PlatformVersion,
347    ) -> Result<(), EncodeError> {
348        Encode::encode(self, encoder)
349    }
350}
351
352impl PlatformVersionedDecode for Ipv6Addr {
353    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
354        decoder: &mut D,
355        _: &PlatformVersion,
356    ) -> Result<Self, DecodeError> {
357        bincode::Decode::decode(decoder)
358    }
359}
360impl_platform_versioned_borrow_decode!(Ipv6Addr);
361
362impl PlatformVersionEncode for SocketAddr {
363    fn platform_encode<E: Encoder>(
364        &self,
365        encoder: &mut E,
366        _: &PlatformVersion,
367    ) -> Result<(), EncodeError> {
368        Encode::encode(self, encoder)
369    }
370}
371
372impl PlatformVersionedDecode for SocketAddr {
373    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
374        decoder: &mut D,
375        _: &PlatformVersion,
376    ) -> Result<Self, DecodeError> {
377        bincode::Decode::decode(decoder)
378    }
379}
380impl_platform_versioned_borrow_decode!(SocketAddr);
381
382impl PlatformVersionEncode for SocketAddrV4 {
383    fn platform_encode<E: Encoder>(
384        &self,
385        encoder: &mut E,
386        _: &PlatformVersion,
387    ) -> Result<(), EncodeError> {
388        Encode::encode(self, encoder)
389    }
390}
391
392impl PlatformVersionedDecode for SocketAddrV4 {
393    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
394        decoder: &mut D,
395        _: &PlatformVersion,
396    ) -> Result<Self, DecodeError> {
397        bincode::Decode::decode(decoder)
398    }
399}
400impl_platform_versioned_borrow_decode!(SocketAddrV4);
401
402impl PlatformVersionEncode for SocketAddrV6 {
403    fn platform_encode<E: Encoder>(
404        &self,
405        encoder: &mut E,
406        _: &PlatformVersion,
407    ) -> Result<(), EncodeError> {
408        Encode::encode(self, encoder)
409    }
410}
411
412impl PlatformVersionedDecode for SocketAddrV6 {
413    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
414        decoder: &mut D,
415        _: &PlatformVersion,
416    ) -> Result<Self, DecodeError> {
417        bincode::Decode::decode(decoder)
418    }
419}
420impl_platform_versioned_borrow_decode!(SocketAddrV6);
421
422impl<K, V, S> PlatformVersionEncode for HashMap<K, V, S>
423where
424    K: PlatformVersionEncode,
425    V: PlatformVersionEncode,
426{
427    fn platform_encode<E: Encoder>(
428        &self,
429        encoder: &mut E,
430        platform_version: &PlatformVersion,
431    ) -> Result<(), EncodeError> {
432        crate::enc::encode_slice_len(encoder, self.len())?;
433        for (k, v) in self.iter() {
434            PlatformVersionEncode::platform_encode(k, encoder, platform_version)?;
435            PlatformVersionEncode::platform_encode(v, encoder, platform_version)?;
436        }
437        Ok(())
438    }
439}
440
441impl<K, V, S> PlatformVersionedDecode for HashMap<K, V, S>
442where
443    K: PlatformVersionedDecode + Eq + std::hash::Hash,
444    V: PlatformVersionedDecode,
445    S: std::hash::BuildHasher + Default,
446{
447    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
448        decoder: &mut D,
449        platform_version: &PlatformVersion,
450    ) -> Result<Self, DecodeError> {
451        let len = crate::de::decode_slice_len(decoder)?;
452        decoder.claim_container_read::<(K, V)>(len)?;
453
454        let hash_builder: S = Default::default();
455        let mut map = HashMap::with_capacity_and_hasher(len, hash_builder);
456        for _ in 0..len {
457            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
458            decoder.unclaim_bytes_read(core::mem::size_of::<(K, V)>());
459
460            let k = K::platform_versioned_decode(decoder, platform_version)?;
461            let v = V::platform_versioned_decode(decoder, platform_version)?;
462            map.insert(k, v);
463        }
464        Ok(map)
465    }
466}
467impl<'de, K, V, S> PlatformVersionedBorrowDecode<'de> for HashMap<K, V, S>
468where
469    K: PlatformVersionedBorrowDecode<'de> + Eq + std::hash::Hash,
470    V: PlatformVersionedBorrowDecode<'de>,
471    S: std::hash::BuildHasher + Default,
472{
473    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
474        decoder: &mut D,
475        platform_version: &PlatformVersion,
476    ) -> Result<Self, DecodeError> {
477        let len = crate::de::decode_slice_len(decoder)?;
478        decoder.claim_container_read::<(K, V)>(len)?;
479
480        let hash_builder: S = Default::default();
481        let mut map = HashMap::with_capacity_and_hasher(len, hash_builder);
482        for _ in 0..len {
483            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
484            decoder.unclaim_bytes_read(core::mem::size_of::<(K, V)>());
485
486            let k = K::platform_versioned_borrow_decode(decoder, platform_version)?;
487            let v = V::platform_versioned_borrow_decode(decoder, platform_version)?;
488            map.insert(k, v);
489        }
490        Ok(map)
491    }
492}
493
494impl<T, S> PlatformVersionedDecode for HashSet<T, S>
495where
496    T: PlatformVersionedDecode + Eq + Hash,
497    S: std::hash::BuildHasher + Default,
498{
499    fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
500        decoder: &mut D,
501        platform_version: &PlatformVersion,
502    ) -> Result<Self, DecodeError> {
503        let len = crate::de::decode_slice_len(decoder)?;
504        decoder.claim_container_read::<T>(len)?;
505
506        let hash_builder: S = Default::default();
507        let mut map: HashSet<T, S> = HashSet::with_capacity_and_hasher(len, hash_builder);
508        for _ in 0..len {
509            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
510            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
511
512            let key = T::platform_versioned_decode(decoder, platform_version)?;
513            map.insert(key);
514        }
515        Ok(map)
516    }
517}
518
519impl<'de, T, S> PlatformVersionedBorrowDecode<'de> for HashSet<T, S>
520where
521    T: PlatformVersionedBorrowDecode<'de> + Eq + Hash,
522    S: std::hash::BuildHasher + Default,
523{
524    fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
525        decoder: &mut D,
526        platform_version: &PlatformVersion,
527    ) -> Result<Self, DecodeError> {
528        let len = crate::de::decode_slice_len(decoder)?;
529        decoder.claim_container_read::<T>(len)?;
530
531        let mut map = HashSet::with_capacity_and_hasher(len, S::default());
532        for _ in 0..len {
533            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
534            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
535
536            let key = T::platform_versioned_borrow_decode(decoder, platform_version)?;
537            map.insert(key);
538        }
539        Ok(map)
540    }
541}
542
543impl<T, S> PlatformVersionEncode for HashSet<T, S>
544where
545    T: PlatformVersionEncode,
546{
547    fn platform_encode<E: Encoder>(
548        &self,
549        encoder: &mut E,
550        platform_version: &PlatformVersion,
551    ) -> Result<(), EncodeError> {
552        crate::enc::encode_slice_len(encoder, self.len())?;
553        for item in self.iter() {
554            item.platform_encode(encoder, platform_version)?;
555        }
556        Ok(())
557    }
558}
559
560#[cfg(test)]
561#[allow(clippy::needless_borrows_for_generic_args)]
562mod tests {
563    use super::*;
564    use bincode::config;
565
566    fn cfg() -> impl bincode::config::Config {
567        config::standard().with_big_endian().with_no_limit()
568    }
569
570    fn pv() -> &'static PlatformVersion {
571        PlatformVersion::first()
572    }
573
574    fn round_trip<T>(value: T) -> T
575    where
576        T: PlatformVersionEncode + crate::PlatformVersionedDecode,
577    {
578        let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
579        crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap()
580    }
581
582    // -----------------------------------------------------------------------
583    // HashMap
584    // -----------------------------------------------------------------------
585
586    #[test]
587    fn hash_map_round_trip() {
588        let mut map = HashMap::new();
589        map.insert("a".to_string(), 1u32);
590        map.insert("b".to_string(), 2);
591        let decoded = round_trip(map.clone());
592        assert_eq!(decoded, map);
593    }
594
595    #[test]
596    fn hash_map_empty_round_trip() {
597        let map: HashMap<String, u32> = HashMap::new();
598        let decoded = round_trip(map.clone());
599        assert_eq!(decoded, map);
600    }
601
602    // -----------------------------------------------------------------------
603    // HashSet
604    // -----------------------------------------------------------------------
605
606    #[test]
607    fn hash_set_round_trip() {
608        let mut set = HashSet::new();
609        set.insert(10u32);
610        set.insert(20);
611        set.insert(30);
612        let decoded = round_trip(set.clone());
613        assert_eq!(decoded, set);
614    }
615
616    // -----------------------------------------------------------------------
617    // Mutex
618    // -----------------------------------------------------------------------
619
620    #[test]
621    fn mutex_round_trip() {
622        let value = Mutex::new(42u32);
623        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
624        let decoded: Mutex<u32> =
625            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
626        assert_eq!(*decoded.lock().unwrap(), 42);
627    }
628
629    // -----------------------------------------------------------------------
630    // RwLock
631    // -----------------------------------------------------------------------
632
633    #[test]
634    fn rwlock_round_trip() {
635        let value = RwLock::new(99u32);
636        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
637        let decoded: RwLock<u32> =
638            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
639        assert_eq!(*decoded.read().unwrap(), 99);
640    }
641
642    // -----------------------------------------------------------------------
643    // CString / &CStr
644    // -----------------------------------------------------------------------
645
646    #[test]
647    fn cstring_round_trip() {
648        let value = CString::new("hello").unwrap();
649        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
650        let decoded: CString =
651            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
652        assert_eq!(decoded, value);
653    }
654
655    #[test]
656    fn cstr_encode() {
657        let cstr = CString::new("test").unwrap();
658        let cstr_ref: &CStr = cstr.as_c_str();
659        let encoded = crate::platform_encode_to_vec(&cstr_ref, cfg(), pv()).unwrap();
660        let decoded: CString =
661            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
662        assert_eq!(decoded.as_c_str(), cstr_ref);
663    }
664
665    // -----------------------------------------------------------------------
666    // SystemTime
667    // -----------------------------------------------------------------------
668
669    #[test]
670    fn system_time_round_trip() {
671        let value = SystemTime::now();
672        let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
673        let decoded: SystemTime =
674            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
675        assert_eq!(decoded, value);
676    }
677
678    // -----------------------------------------------------------------------
679    // PathBuf / &Path
680    // -----------------------------------------------------------------------
681
682    #[test]
683    fn pathbuf_encode() {
684        let value = PathBuf::from("/tmp/test");
685        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
686        assert!(!encoded.is_empty());
687    }
688
689    #[test]
690    fn path_ref_encode() {
691        let path = Path::new("/tmp/test");
692        let encoded = crate::platform_encode_to_vec(&path, cfg(), pv()).unwrap();
693        assert!(!encoded.is_empty());
694    }
695
696    #[test]
697    fn path_borrow_decode() {
698        let path = Path::new("/usr/local");
699        let encoded = crate::platform_encode_to_vec(&path, cfg(), pv()).unwrap();
700        let decoded: &Path =
701            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
702        assert_eq!(decoded, path);
703    }
704
705    // -----------------------------------------------------------------------
706    // IP addresses
707    // -----------------------------------------------------------------------
708
709    #[test]
710    fn ipv4_round_trip() {
711        let value = Ipv4Addr::new(192, 168, 1, 1);
712        assert_eq!(round_trip(value), value);
713    }
714
715    #[test]
716    fn ipv6_round_trip() {
717        let value = Ipv6Addr::LOCALHOST;
718        assert_eq!(round_trip(value), value);
719    }
720
721    #[test]
722    fn ip_addr_v4_round_trip() {
723        let value = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1));
724        assert_eq!(round_trip(value), value);
725    }
726
727    #[test]
728    fn ip_addr_v6_round_trip() {
729        let value = IpAddr::V6(Ipv6Addr::LOCALHOST);
730        assert_eq!(round_trip(value), value);
731    }
732
733    // -----------------------------------------------------------------------
734    // Socket addresses
735    // -----------------------------------------------------------------------
736
737    #[test]
738    fn socket_addr_v4_round_trip() {
739        let value = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
740        assert_eq!(round_trip(value), value);
741    }
742
743    #[test]
744    fn socket_addr_v6_round_trip() {
745        let value = SocketAddrV6::new(Ipv6Addr::LOCALHOST, 443, 0, 0);
746        assert_eq!(round_trip(value), value);
747    }
748
749    #[test]
750    fn socket_addr_round_trip() {
751        let value = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 3000));
752        assert_eq!(round_trip(value), value);
753    }
754
755    // -----------------------------------------------------------------------
756    // Borrow-decode paths for std types
757    // -----------------------------------------------------------------------
758
759    #[test]
760    fn hash_map_borrow_decode() {
761        let mut map = HashMap::new();
762        map.insert(1u32, 10u32);
763        map.insert(2, 20);
764        let encoded = crate::platform_encode_to_vec(&map, cfg(), pv()).unwrap();
765        let decoded: HashMap<u32, u32> =
766            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
767        assert_eq!(decoded, map);
768    }
769
770    #[test]
771    fn hash_set_borrow_decode() {
772        let mut set = HashSet::new();
773        set.insert(1u32);
774        set.insert(2);
775        let encoded = crate::platform_encode_to_vec(&set, cfg(), pv()).unwrap();
776        let decoded: HashSet<u32> =
777            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
778        assert_eq!(decoded, set);
779    }
780
781    #[test]
782    fn mutex_borrow_decode() {
783        let value = Mutex::new(42u32);
784        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
785        let decoded: Mutex<u32> =
786            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
787        assert_eq!(*decoded.lock().unwrap(), 42);
788    }
789
790    #[test]
791    fn rwlock_borrow_decode() {
792        let value = RwLock::new(99u32);
793        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
794        let decoded: RwLock<u32> =
795            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
796        assert_eq!(*decoded.read().unwrap(), 99);
797    }
798}