bitcode/derive/
smart_ptr.rs

1use crate::coder::{Buffer, Decoder, Encoder, Result, View};
2use crate::derive::{Decode, Encode};
3use alloc::vec::Vec;
4use core::num::NonZeroUsize;
5use core::ops::Deref;
6
7pub struct DerefEncoder<T: Encode + ?Sized>(T::Encoder);
8
9// Can't derive since it would bound T: Default.
10impl<T: Encode + ?Sized> Default for DerefEncoder<T> {
11    fn default() -> Self {
12        Self(Default::default())
13    }
14}
15
16impl<D: Deref<Target = T>, T: Encode + ?Sized> Encoder<D> for DerefEncoder<T> {
17    #[inline(always)]
18    fn encode(&mut self, t: &D) {
19        self.0.encode(t);
20    }
21}
22
23impl<T: Encode + ?Sized> Buffer for DerefEncoder<T> {
24    fn collect_into(&mut self, out: &mut Vec<u8>) {
25        self.0.collect_into(out);
26    }
27    fn reserve(&mut self, additional: NonZeroUsize) {
28        self.0.reserve(additional);
29    }
30}
31
32/// Decodes a `T` and then converts it with [`From`]. For example `T` -> `Box<T>` and `Vec<T>` -> `Box<[T]>`.
33pub struct FromDecoder<'a, T: Decode<'a>>(T::Decoder);
34
35// Can't derive since it would bound T: Default.
36impl<'a, T: Decode<'a>> Default for FromDecoder<'a, T> {
37    fn default() -> Self {
38        Self(Default::default())
39    }
40}
41
42impl<'a, T: Decode<'a>> View<'a> for FromDecoder<'a, T> {
43    fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
44        self.0.populate(input, length)
45    }
46}
47
48impl<'a, F: From<T>, T: Decode<'a>> Decoder<'a, F> for FromDecoder<'a, T> {
49    #[inline(always)]
50    fn decode(&mut self) -> F {
51        F::from(self.0.decode())
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use crate::{decode, encode};
58    use alloc::boxed::Box;
59    use alloc::string::ToString;
60
61    #[test]
62    fn box_() {
63        let v = Box::new(123u8);
64        assert_eq!(decode::<Box<u8>>(&encode(&v)).unwrap(), v);
65    }
66
67    #[test]
68    fn box_slice() {
69        let v = vec![123u8].into_boxed_slice();
70        assert_eq!(decode::<Box<[u8]>>(&encode(&v)).unwrap(), v);
71    }
72
73    #[test]
74    fn box_str() {
75        let v = "box".to_string().into_boxed_str();
76        assert_eq!(decode::<Box<str>>(&encode(&v)).unwrap(), v);
77    }
78}