vex_cdc/
encode.rs

1/// Simplifies encoding data with the [`Encode`] trait.
2pub struct MessageEncoder<'a> {
3    data: &'a mut [u8],
4    pos: usize,
5}
6
7impl<'a> MessageEncoder<'a> {
8    pub const fn new(data: &'a mut [u8]) -> Self {
9        Self { data, pos: 0 }
10    }
11
12    pub const fn new_with_position(data: &'a mut [u8], pos: usize) -> Self {
13        Self { data, pos }
14    }
15
16    pub fn write<T: Encode>(&mut self, value: &T) {
17        let data = &mut self.data[self.pos..];
18
19        value.encode(data);
20        self.pos += value.size();
21    }
22
23    #[inline]
24    pub const fn set_position(&mut self, pos: usize) {
25        self.pos = pos;
26    }
27
28    #[inline]
29    #[must_use]
30    pub const fn position(&self) -> usize {
31        self.pos
32    }
33
34    #[inline]
35    #[must_use]
36    pub const fn get_ref(&self) -> &[u8] {
37        self.data
38    }
39}
40
41/// A type that can be encoded into a sequence of bytes.
42pub trait Encode {
43    /// Returns the number of bytes this value will take when encoded.
44    fn size(&self) -> usize;
45
46    /// Encodes this instance into the provided byte slice.
47    fn encode(&self, data: &mut [u8]);
48}
49
50macro_rules! impl_encode_for_primitive {
51    ($($t:ty),*) => {
52        $(
53            impl Encode for $t {
54                fn size(&self) -> usize {
55                    size_of::<Self>()
56                }
57
58                fn encode(&self, data: &mut [u8]) {
59                    data[..size_of::<Self>()].copy_from_slice(&self.to_le_bytes());
60                }
61            }
62        )*
63    };
64}
65
66impl_encode_for_primitive!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
67
68impl Encode for () {
69    fn size(&self) -> usize {
70        0
71    }
72    fn encode(&self, _data: &mut [u8]) {}
73}
74
75impl Encode for &[u8] {
76    fn size(&self) -> usize {
77        self.len()
78    }
79
80    fn encode(&self, data: &mut [u8]) {
81        data[..self.len()].copy_from_slice(self);
82    }
83}
84
85impl<const N: usize> Encode for [u8; N] {
86    fn size(&self) -> usize {
87        N
88    }
89
90    fn encode(&self, data: &mut [u8]) {
91        data[..N].copy_from_slice(self);
92    }
93}
94
95impl Encode for alloc::vec::Vec<u8> {
96    fn size(&self) -> usize {
97        self.len()
98    }
99
100    fn encode(&self, data: &mut [u8]) {
101        self.as_slice().encode(data)
102    }
103}