bin_proto/impls/
container.rs

1macro_rules! impl_container_write {
2    (
3        $ty:ident<$($a:lifetime,)? T $(: ?$tbound0:ident $(+ $tbound1:ident + $tbound2:lifetime)?)?>
4        $(=> $f:ident)?
5    ) => {
6        impl<$($a,)? Ctx, Tag, T> $crate::BitEncode<Ctx, Tag> for $ty<$($a,)? T>
7        where
8            T: $crate::BitEncode<Ctx, Tag> $(+ ?$tbound0 $(+ $tbound1 + $tbound2)?)?,
9        {
10            fn encode<W, E>(
11                &self,
12                write: &mut W,
13                ctx: &mut Ctx,
14                tag: Tag,
15            ) -> $crate::Result<()>
16            where
17                W: ::bitstream_io::BitWrite,
18                E: ::bitstream_io::Endianness,
19            {
20                use core::ops::Deref;
21
22                $crate::BitEncode::encode::<_, E>(
23                    self $(.$f()?)? .deref(),
24                    write,
25                    ctx,
26                    tag,
27                )
28            }
29        }
30    };
31}
32
33#[allow(unused)]
34macro_rules! impl_container_read {
35    ($ty:ident<T $(: ?$tbound:ident)?>) => {
36        impl<Ctx, Tag, T> $crate::BitDecode<Ctx, Tag> for $ty<T>
37        where
38            T: $crate::BitDecode<Ctx, Tag> $(+ ?$tbound)?,
39        {
40            fn decode<R, E>(read: &mut R, ctx: &mut Ctx, tag: Tag) -> $crate::Result<Self>
41            where
42                R: ::bitstream_io::BitRead,
43                E: ::bitstream_io::Endianness,
44            {
45                Ok($ty::new($crate::BitDecode::decode::<_, E>(read, ctx, tag)?))
46            }
47        }
48    };
49}
50
51#[cfg(feature = "alloc")]
52mod box_ {
53    use alloc::boxed::Box;
54
55    impl_container_write!(Box<T: ?Sized>);
56    impl_container_read!(Box<T: ?Sized>);
57    test_codec!(Box<u8>; Box::new(1) => [0x01]);
58    test_roundtrip!(Box<u8>);
59}
60
61#[cfg(feature = "alloc")]
62mod rc {
63    use alloc::rc::Rc;
64
65    impl_container_write!(Rc<T: ?Sized>);
66    impl_container_read!(Rc<T: ?Sized>);
67    test_codec!(Rc<u8>; Rc::new(1) => [0x01]);
68    test_roundtrip!(Rc<u8>);
69}
70
71#[cfg(feature = "alloc")]
72mod arc {
73    use alloc::sync::Arc;
74
75    impl_container_write!(Arc<T: ?Sized>);
76    impl_container_read!(Arc<T: ?Sized>);
77    test_codec!(Arc<u8>; Arc::new(1) => [0x01]);
78    test_roundtrip!(Arc<u8>);
79}
80
81#[cfg(feature = "alloc")]
82mod cow {
83    use alloc::borrow::{Cow, ToOwned};
84
85    impl_container_write!(Cow<'a, T: ?Sized + ToOwned + 'a>);
86    test_encode!(Cow<u8>; Cow::Owned(1) => [0x01]);
87}
88
89mod cell {
90    use core::cell::Cell;
91
92    use bitstream_io::{BitWrite, Endianness};
93
94    use crate::{BitEncode, Result};
95
96    impl<Ctx, Tag, T> BitEncode<Ctx, Tag> for Cell<T>
97    where
98        T: BitEncode<Ctx, Tag> + Copy,
99    {
100        fn encode<W, E>(&self, write: &mut W, ctx: &mut Ctx, tag: Tag) -> Result<()>
101        where
102            W: BitWrite,
103            E: Endianness,
104        {
105            self.get().encode::<_, E>(write, ctx, tag)
106        }
107    }
108
109    test_encode!(Cell<u8>; Cell::new(1) => [0x01]);
110}
111
112#[cfg(feature = "std")]
113mod rwlock {
114    use std::sync::RwLock;
115
116    impl_container_write!(RwLock<T: ?Sized> => read);
117
118    #[cfg(test)]
119    mod tests {
120        use alloc::vec::Vec;
121
122        use bitstream_io::{BigEndian, BitWriter};
123
124        use crate::BitEncode;
125
126        use super::*;
127
128        #[test]
129        fn encode() {
130            let mut buffer: Vec<u8> = Vec::new();
131            BitEncode::encode::<_, BigEndian>(
132                &RwLock::new(1u8),
133                &mut BitWriter::endian(&mut buffer, BigEndian),
134                &mut (),
135                (),
136            )
137            .unwrap();
138            assert_eq!([1], *buffer);
139        }
140    }
141}
142
143#[cfg(feature = "std")]
144mod mutex {
145    use std::sync::Mutex;
146
147    impl_container_write!(Mutex<T: ?Sized> => lock);
148    test_encode!(Mutex<u8>; Mutex::new(1) => [0x01]);
149}
150
151mod ref_cell {
152    use core::cell::RefCell;
153
154    impl_container_write!(RefCell<T: ?Sized> => try_borrow);
155    test_encode!(RefCell<u8>; RefCell::new(1) => [0x01]);
156}