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)]
561mod tests {
562    use super::*;
563    use bincode::config;
564
565    fn cfg() -> impl bincode::config::Config {
566        config::standard().with_big_endian().with_no_limit()
567    }
568
569    fn pv() -> &'static PlatformVersion {
570        PlatformVersion::first()
571    }
572
573    fn round_trip<T>(value: T) -> T
574    where
575        T: PlatformVersionEncode + crate::PlatformVersionedDecode,
576    {
577        let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
578        crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap()
579    }
580
581    // -----------------------------------------------------------------------
582    // HashMap
583    // -----------------------------------------------------------------------
584
585    #[test]
586    fn hash_map_round_trip() {
587        let mut map = HashMap::new();
588        map.insert("a".to_string(), 1u32);
589        map.insert("b".to_string(), 2);
590        let decoded = round_trip(map.clone());
591        assert_eq!(decoded, map);
592    }
593
594    #[test]
595    fn hash_map_empty_round_trip() {
596        let map: HashMap<String, u32> = HashMap::new();
597        let decoded = round_trip(map.clone());
598        assert_eq!(decoded, map);
599    }
600
601    // -----------------------------------------------------------------------
602    // HashSet
603    // -----------------------------------------------------------------------
604
605    #[test]
606    fn hash_set_round_trip() {
607        let mut set = HashSet::new();
608        set.insert(10u32);
609        set.insert(20);
610        set.insert(30);
611        let decoded = round_trip(set.clone());
612        assert_eq!(decoded, set);
613    }
614
615    // -----------------------------------------------------------------------
616    // Mutex
617    // -----------------------------------------------------------------------
618
619    #[test]
620    fn mutex_round_trip() {
621        let value = Mutex::new(42u32);
622        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
623        let decoded: Mutex<u32> =
624            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
625        assert_eq!(*decoded.lock().unwrap(), 42);
626    }
627
628    // -----------------------------------------------------------------------
629    // RwLock
630    // -----------------------------------------------------------------------
631
632    #[test]
633    fn rwlock_round_trip() {
634        let value = RwLock::new(99u32);
635        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
636        let decoded: RwLock<u32> =
637            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
638        assert_eq!(*decoded.read().unwrap(), 99);
639    }
640
641    // -----------------------------------------------------------------------
642    // CString / &CStr
643    // -----------------------------------------------------------------------
644
645    #[test]
646    fn cstring_round_trip() {
647        let value = CString::new("hello").unwrap();
648        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
649        let decoded: CString =
650            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
651        assert_eq!(decoded, value);
652    }
653
654    #[test]
655    fn cstr_encode() {
656        let cstr = CString::new("test").unwrap();
657        let cstr_ref: &CStr = cstr.as_c_str();
658        let encoded = crate::platform_encode_to_vec(&cstr_ref, cfg(), pv()).unwrap();
659        let decoded: CString =
660            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
661        assert_eq!(decoded.as_c_str(), cstr_ref);
662    }
663
664    // -----------------------------------------------------------------------
665    // SystemTime
666    // -----------------------------------------------------------------------
667
668    #[test]
669    fn system_time_round_trip() {
670        let value = SystemTime::now();
671        let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
672        let decoded: SystemTime =
673            crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
674        assert_eq!(decoded, value);
675    }
676
677    // -----------------------------------------------------------------------
678    // PathBuf / &Path
679    // -----------------------------------------------------------------------
680
681    #[test]
682    fn pathbuf_encode() {
683        let value = PathBuf::from("/tmp/test");
684        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
685        assert!(!encoded.is_empty());
686    }
687
688    #[test]
689    fn path_ref_encode() {
690        let path = Path::new("/tmp/test");
691        let encoded = crate::platform_encode_to_vec(&path, cfg(), pv()).unwrap();
692        assert!(!encoded.is_empty());
693    }
694
695    #[test]
696    fn path_borrow_decode() {
697        let path = Path::new("/usr/local");
698        let encoded = crate::platform_encode_to_vec(&path, cfg(), pv()).unwrap();
699        let decoded: &Path =
700            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
701        assert_eq!(decoded, path);
702    }
703
704    // -----------------------------------------------------------------------
705    // IP addresses
706    // -----------------------------------------------------------------------
707
708    #[test]
709    fn ipv4_round_trip() {
710        let value = Ipv4Addr::new(192, 168, 1, 1);
711        assert_eq!(round_trip(value), value);
712    }
713
714    #[test]
715    fn ipv6_round_trip() {
716        let value = Ipv6Addr::LOCALHOST;
717        assert_eq!(round_trip(value), value);
718    }
719
720    #[test]
721    fn ip_addr_v4_round_trip() {
722        let value = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1));
723        assert_eq!(round_trip(value), value);
724    }
725
726    #[test]
727    fn ip_addr_v6_round_trip() {
728        let value = IpAddr::V6(Ipv6Addr::LOCALHOST);
729        assert_eq!(round_trip(value), value);
730    }
731
732    // -----------------------------------------------------------------------
733    // Socket addresses
734    // -----------------------------------------------------------------------
735
736    #[test]
737    fn socket_addr_v4_round_trip() {
738        let value = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
739        assert_eq!(round_trip(value), value);
740    }
741
742    #[test]
743    fn socket_addr_v6_round_trip() {
744        let value = SocketAddrV6::new(Ipv6Addr::LOCALHOST, 443, 0, 0);
745        assert_eq!(round_trip(value), value);
746    }
747
748    #[test]
749    fn socket_addr_round_trip() {
750        let value = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 3000));
751        assert_eq!(round_trip(value), value);
752    }
753
754    // -----------------------------------------------------------------------
755    // Borrow-decode paths for std types
756    // -----------------------------------------------------------------------
757
758    #[test]
759    fn hash_map_borrow_decode() {
760        let mut map = HashMap::new();
761        map.insert(1u32, 10u32);
762        map.insert(2, 20);
763        let encoded = crate::platform_encode_to_vec(&map, cfg(), pv()).unwrap();
764        let decoded: HashMap<u32, u32> =
765            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
766        assert_eq!(decoded, map);
767    }
768
769    #[test]
770    fn hash_set_borrow_decode() {
771        let mut set = HashSet::new();
772        set.insert(1u32);
773        set.insert(2);
774        let encoded = crate::platform_encode_to_vec(&set, cfg(), pv()).unwrap();
775        let decoded: HashSet<u32> =
776            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
777        assert_eq!(decoded, set);
778    }
779
780    #[test]
781    fn mutex_borrow_decode() {
782        let value = Mutex::new(42u32);
783        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
784        let decoded: Mutex<u32> =
785            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
786        assert_eq!(*decoded.lock().unwrap(), 42);
787    }
788
789    #[test]
790    fn rwlock_borrow_decode() {
791        let value = RwLock::new(99u32);
792        let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
793        let decoded: RwLock<u32> =
794            crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
795        assert_eq!(*decoded.read().unwrap(), 99);
796    }
797}