bitcode/derive/
smart_ptr.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use crate::coder::{Buffer, Decoder, Encoder, Result, View};
use crate::derive::{Decode, Encode};
use alloc::vec::Vec;
use core::num::NonZeroUsize;
use core::ops::Deref;

pub struct DerefEncoder<T: Encode + ?Sized>(T::Encoder);

// Can't derive since it would bound T: Default.
impl<T: Encode + ?Sized> Default for DerefEncoder<T> {
    fn default() -> Self {
        Self(Default::default())
    }
}

impl<D: Deref<Target = T>, T: Encode + ?Sized> Encoder<D> for DerefEncoder<T> {
    #[inline(always)]
    fn encode(&mut self, t: &D) {
        self.0.encode(t);
    }
}

impl<T: Encode + ?Sized> Buffer for DerefEncoder<T> {
    fn collect_into(&mut self, out: &mut Vec<u8>) {
        self.0.collect_into(out);
    }
    fn reserve(&mut self, additional: NonZeroUsize) {
        self.0.reserve(additional);
    }
}

/// Decodes a `T` and then converts it with [`From`]. For `T` -> `Box<T>` and `Vec<T>` -> `Box<[T]>`.
pub struct FromDecoder<'a, T: Decode<'a>>(T::Decoder);

// Can't derive since it would bound T: Default.
impl<'a, T: Decode<'a>> Default for FromDecoder<'a, T> {
    fn default() -> Self {
        Self(Default::default())
    }
}

impl<'a, T: Decode<'a>> View<'a> for FromDecoder<'a, T> {
    fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
        self.0.populate(input, length)
    }
}

impl<'a, F: From<T>, T: Decode<'a>> Decoder<'a, F> for FromDecoder<'a, T> {
    #[inline(always)]
    fn decode(&mut self) -> F {
        F::from(self.0.decode())
    }
}

#[cfg(test)]
mod tests {
    use crate::{decode, encode};
    use alloc::boxed::Box;
    use alloc::string::ToString;

    #[test]
    fn box_() {
        let v = Box::new(123u8);
        assert_eq!(decode::<Box<u8>>(&encode(&v)).unwrap(), v);
    }

    #[test]
    fn box_slice() {
        let v = vec![123u8].into_boxed_slice();
        assert_eq!(decode::<Box<[u8]>>(&encode(&v)).unwrap(), v);
    }

    #[test]
    fn box_str() {
        let v = "box".to_string().into_boxed_str();
        assert_eq!(decode::<Box<str>>(&encode(&v)).unwrap(), v);
    }
}