bitcode/derive/
impls.rs

1use crate::bool::{BoolDecoder, BoolEncoder};
2use crate::coder::{Buffer, Decoder, Encoder, Result, View};
3use crate::derive::array::{ArrayDecoder, ArrayEncoder};
4use crate::derive::empty::EmptyCoder;
5use crate::derive::map::{MapDecoder, MapEncoder};
6use crate::derive::option::{OptionDecoder, OptionEncoder};
7use crate::derive::result::{ResultDecoder, ResultEncoder};
8use crate::derive::smart_ptr::{DerefEncoder, FromDecoder};
9use crate::derive::vec::{VecDecoder, VecEncoder};
10use crate::derive::{Decode, Encode};
11use crate::f32::{F32Decoder, F32Encoder};
12use crate::int::{CheckedIntDecoder, IntDecoder, IntEncoder};
13use crate::str::{StrDecoder, StrEncoder};
14use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
15use alloc::string::String;
16use alloc::vec::Vec;
17use core::marker::PhantomData;
18use core::mem::MaybeUninit;
19use core::num::*;
20
21macro_rules! impl_both {
22    ($t:ty, $encoder:ident, $decoder:ident) => {
23        impl Encode for $t {
24            type Encoder = $encoder;
25        }
26        impl<'a> Decode<'a> for $t {
27            type Decoder = $decoder<'a>;
28        }
29    };
30}
31pub(crate) use impl_both;
32impl_both!(bool, BoolEncoder, BoolDecoder);
33impl_both!(f32, F32Encoder, F32Decoder);
34impl_both!(String, StrEncoder, StrDecoder);
35
36macro_rules! impl_int {
37    ($($t:ty),+) => {
38        $(
39            impl Encode for $t {
40                type Encoder = IntEncoder<$t>;
41            }
42            impl<'a> Decode<'a> for $t {
43                type Decoder = IntDecoder<'a, $t>;
44            }
45        )+
46    }
47}
48impl_int!(u8, u16, u32, u64, u128, usize);
49impl_int!(i8, i16, i32, i64, i128, isize);
50// TODO F64Encoder (once F32Encoder is sufficiently optimized).
51impl Encode for f64 {
52    type Encoder = IntEncoder<u64>;
53}
54impl<'a> Decode<'a> for f64 {
55    type Decoder = IntDecoder<'a, u64>;
56}
57
58macro_rules! impl_checked_int {
59    ($($a:ty => $b:ty),+) => {
60        $(
61            impl Encode for $a {
62                type Encoder = IntEncoder<$b>;
63            }
64            impl<'a> Decode<'a> for $a {
65                type Decoder = CheckedIntDecoder<'a, $a, $b>;
66            }
67        )+
68    }
69}
70impl_checked_int!(NonZeroU8 => u8, NonZeroU16 => u16, NonZeroU32 => u32, NonZeroU64 => u64, NonZeroU128 => u128, NonZeroUsize => usize);
71impl_checked_int!(NonZeroI8 => i8, NonZeroI16 => i16, NonZeroI32 => i32, NonZeroI64 => i64, NonZeroI128 => i128, NonZeroIsize => isize);
72impl_checked_int!(char => u32);
73
74macro_rules! impl_t {
75    ($t:ident, $encoder:ident, $decoder:ident) => {
76        impl<T: Encode> Encode for $t<T> {
77            type Encoder = $encoder<T>;
78        }
79        impl<'a, T: Decode<'a>> Decode<'a> for $t<T> {
80            type Decoder = $decoder<'a, T>;
81        }
82    };
83}
84impl_t!(LinkedList, VecEncoder, VecDecoder);
85impl_t!(Option, OptionEncoder, OptionDecoder);
86impl_t!(Vec, VecEncoder, VecDecoder);
87impl_t!(VecDeque, VecEncoder, VecDecoder);
88
89macro_rules! impl_smart_ptr {
90    ($(::$ptr: ident)*) => {
91        impl<T: Encode + ?Sized> Encode for $(::$ptr)*<T> {
92            type Encoder = DerefEncoder<T>;
93        }
94
95        impl<'a, T: Decode<'a>> Decode<'a> for $(::$ptr)*<T> {
96            type Decoder = FromDecoder<'a, T>;
97        }
98
99        impl<'a, T: Decode<'a>> Decode<'a> for $(::$ptr)*<[T]> {
100            // TODO avoid Vec<T> allocation for Rc<[T]> and Arc<[T]>.
101            type Decoder = FromDecoder<'a, Vec<T>>;
102        }
103
104        impl<'a> Decode<'a> for $(::$ptr)*<str> {
105            // TODO avoid String allocation for Rc<str> and Arc<str>.
106            type Decoder = FromDecoder<'a, String>;
107        }
108    }
109}
110impl_smart_ptr!(::alloc::boxed::Box);
111impl_smart_ptr!(::alloc::rc::Rc);
112impl_smart_ptr!(::alloc::sync::Arc);
113
114impl<T: Encode, const N: usize> Encode for [T; N] {
115    type Encoder = ArrayEncoder<T, N>;
116}
117impl<'a, T: Decode<'a>, const N: usize> Decode<'a> for [T; N] {
118    type Decoder = ArrayDecoder<'a, T, N>;
119}
120
121// Convenience impls copied from serde etc. Makes Box<T: Encode> work on Box<[T]>.
122impl<T: Encode> Encode for [T] {
123    type Encoder = VecEncoder<T>;
124}
125impl Encode for str {
126    type Encoder = StrEncoder;
127}
128
129// Partial zero copy deserialization like serde.
130impl Encode for &str {
131    type Encoder = StrEncoder;
132}
133impl<'a> Decode<'a> for &'a str {
134    type Decoder = StrDecoder<'a>;
135}
136
137impl<T: Encode> Encode for BinaryHeap<T> {
138    type Encoder = VecEncoder<T>;
139}
140impl<'a, T: Decode<'a> + Ord> Decode<'a> for BinaryHeap<T> {
141    type Decoder = VecDecoder<'a, T>;
142}
143impl<T: Encode> Encode for BTreeSet<T> {
144    type Encoder = VecEncoder<T>;
145}
146impl<'a, T: Decode<'a> + Ord> Decode<'a> for BTreeSet<T> {
147    type Decoder = VecDecoder<'a, T>;
148}
149
150impl<K: Encode, V: Encode> Encode for BTreeMap<K, V> {
151    type Encoder = MapEncoder<K, V>;
152}
153impl<'a, K: Decode<'a> + Ord, V: Decode<'a>> Decode<'a> for BTreeMap<K, V> {
154    type Decoder = MapDecoder<'a, K, V>;
155}
156
157impl<T: Encode, E: Encode> Encode for core::result::Result<T, E> {
158    type Encoder = ResultEncoder<T, E>;
159}
160impl<'a, T: Decode<'a>, E: Decode<'a>> Decode<'a> for core::result::Result<T, E> {
161    type Decoder = ResultDecoder<'a, T, E>;
162}
163
164#[cfg(feature = "std")]
165mod with_std {
166    use super::*;
167    use crate::derive::convert::impl_convert;
168    use core::hash::{BuildHasher, Hash};
169    use std::collections::{HashMap, HashSet};
170
171    impl<T: Encode, S> Encode for HashSet<T, S> {
172        type Encoder = VecEncoder<T>;
173    }
174    impl<'a, T: Decode<'a> + Eq + Hash, S: BuildHasher + Default> Decode<'a> for HashSet<T, S> {
175        type Decoder = VecDecoder<'a, T>;
176    }
177    impl<K: Encode, V: Encode, S> Encode for HashMap<K, V, S> {
178        type Encoder = MapEncoder<K, V>;
179    }
180    impl<'a, K: Decode<'a> + Eq + Hash, V: Decode<'a>, S: BuildHasher + Default> Decode<'a>
181        for HashMap<K, V, S>
182    {
183        type Decoder = MapDecoder<'a, K, V>;
184    }
185
186    macro_rules! impl_ipvx_addr {
187        ($addr: ident, $repr: ident) => {
188            impl_convert!(std::net::$addr, $repr);
189        };
190    }
191
192    impl_ipvx_addr!(Ipv4Addr, u32);
193    impl_ipvx_addr!(Ipv6Addr, u128);
194    impl_convert!(std::net::IpAddr, crate::derive::ip_addr::IpAddrConversion);
195    impl_convert!(
196        std::net::SocketAddrV4,
197        crate::derive::ip_addr::SocketAddrV4Conversion
198    );
199    impl_convert!(
200        std::net::SocketAddrV6,
201        crate::derive::ip_addr::SocketAddrV6Conversion
202    );
203    impl_convert!(
204        std::net::SocketAddr,
205        crate::derive::ip_addr::SocketAddrConversion
206    );
207}
208
209impl<T> Encode for PhantomData<T> {
210    type Encoder = EmptyCoder;
211}
212impl<'a, T> Decode<'a> for PhantomData<T> {
213    type Decoder = EmptyCoder;
214}
215
216macro_rules! impl_tuples {
217    ($(($($n:tt $name:ident)*))+) => {
218        $(
219            #[allow(unused, clippy::unused_unit)]
220            const _: () = {
221                impl<$($name: Encode,)*> Encode for ($($name,)*) {
222                    type Encoder = TupleEncoder<$($name,)*>;
223                }
224
225                pub struct TupleEncoder<$($name: Encode,)*>(
226                    $($name::Encoder,)*
227                );
228
229                impl<$($name: Encode,)*> Default for TupleEncoder<$($name,)*> {
230                    fn default() -> Self {
231                        Self(
232                            $($name::Encoder::default(),)*
233                        )
234                    }
235                }
236
237                impl<$($name: Encode,)*> Encoder<($($name,)*)> for TupleEncoder<$($name,)*> {
238                    #[inline(always)]
239                    fn encode(&mut self, t: &($($name,)*)) {
240                        $(
241                            self.$n.encode(&t.$n);
242                        )*
243                    }
244
245                    // #[inline(always)]
246                    fn encode_vectored<'a>(&mut self, i: impl Iterator<Item=&'a ($($name,)*)> + Clone) where ($($name,)*): 'a {
247                        $(
248                            self.$n.encode_vectored(i.clone().map(|t| &t.$n));
249                        )*
250                    }
251                }
252
253                impl<$($name: Encode,)*> Buffer for TupleEncoder<$($name,)*> {
254                    fn collect_into(&mut self, out: &mut Vec<u8>) {
255                        $(
256                            self.$n.collect_into(out);
257                        )*
258                    }
259
260                    fn reserve(&mut self, length: NonZeroUsize) {
261                        $(
262                            self.$n.reserve(length);
263                        )*
264                    }
265                }
266
267                impl<'a, $($name: Decode<'a>,)*> Decode<'a> for ($($name,)*) {
268                    type Decoder = TupleDecoder<'a, $($name,)*>;
269                }
270
271                pub struct TupleDecoder<'a, $($name: Decode<'a>,)*>(
272                    $($name::Decoder,)*
273                    core::marker::PhantomData<&'a ()>,
274                );
275
276                impl<'a, $($name: Decode<'a>,)*> Default for TupleDecoder<'a, $($name,)*> {
277                    fn default() -> Self {
278                        Self(
279                            $($name::Decoder::default(),)*
280                            Default::default(),
281                        )
282                    }
283                }
284
285                impl<'a, $($name: Decode<'a>,)*> Decoder<'a, ($($name,)*)> for TupleDecoder<'a, $($name,)*> {
286                    #[inline(always)]
287                    fn decode_in_place(&mut self, out: &mut MaybeUninit<($($name,)*)>) {
288                        $(
289                            self.$n.decode_in_place(crate::coder::uninit_field!(out.$n: $name));
290                        )*
291                    }
292                }
293
294                impl<'a, $($name: Decode<'a>,)*> View<'a> for TupleDecoder<'a, $($name,)*> {
295                    fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
296                        $(
297                            self.$n.populate(input, length)?;
298                        )*
299                        Ok(())
300                    }
301                }
302            };
303        )+
304    }
305}
306
307impl_tuples! {
308    ()
309    (0 T0)
310    (0 T0 1 T1)
311    (0 T0 1 T1 2 T2)
312    (0 T0 1 T1 2 T2 3 T3)
313    (0 T0 1 T1 2 T2 3 T3 4 T4)
314    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
315    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
316    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
317    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
318    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
319    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
320    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
321    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
322    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
323    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
324    (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
325}
326
327#[cfg(test)]
328mod tests {
329    use alloc::string::String;
330    use alloc::vec::Vec;
331
332    type Tuple = (u64, u32, u8, i32, u8, u16, i8, (u8, u8, u8, u8), i8);
333    fn bench_data() -> Vec<(Tuple, Option<String>)> {
334        crate::random_data(1000)
335            .into_iter()
336            .map(|t: Tuple| (t, None))
337            .collect()
338    }
339    crate::bench_encode_decode!(tuple_vec: Vec<_>);
340}