dash7_alp/
codec.rs

1#[derive(Debug, Copy, Clone, Hash, PartialEq)]
2pub struct WithOffset<T> {
3    pub offset: usize,
4    pub value: T,
5}
6
7impl<T> WithOffset<T> {
8    pub fn new(offset: usize, value: T) -> Self {
9        Self { offset, value }
10    }
11
12    pub fn new_head(value: T) -> Self {
13        Self::new(0, value)
14    }
15
16    pub fn shift(mut self, n: usize) -> Self {
17        self.offset += n;
18        self
19    }
20
21    pub fn map_value<U, F: FnOnce(T) -> U>(self, f: F) -> WithOffset<U> {
22        let Self { offset, value } = self;
23        WithOffset {
24            offset,
25            value: f(value),
26        }
27    }
28}
29
30#[derive(Debug, Copy, Clone, Hash, PartialEq)]
31pub struct WithSize<T> {
32    pub size: usize,
33    pub value: T,
34}
35
36impl<T> WithSize<T> {
37    pub fn new(size: usize, value: T) -> Self {
38        Self { size, value }
39    }
40
41    pub fn add(&mut self, n: usize) {
42        self.size += n;
43    }
44
45    pub fn map_value<U, F: FnOnce(T) -> U>(self, f: F) -> WithSize<U> {
46        let Self { size, value } = self;
47        WithSize {
48            size,
49            value: f(value),
50        }
51    }
52}
53
54// TODO Bad name
55#[derive(Debug, Copy, Clone, Hash, PartialEq)]
56pub enum StdError {
57    MissingBytes(usize),
58}
59
60/// Trait implemented by any item that is encodable to a byte array and decodable from a byte
61/// array.
62pub trait Codec: core::marker::Sized {
63    type Error;
64
65    /// Computes the number of bytes required to encode the item.
66    fn encoded_size(&self) -> usize;
67
68    /// Encode the item into a given byte array.
69    /// # Safety
70    /// You have to ensure there is enough space in the given array (compared to what
71    /// [encoded_size](#encoded_size) returns) or this method will panic.
72    /// # Panics
73    /// Panics if the given `out` array is too small.
74    unsafe fn encode_in(&self, out: &mut [u8]) -> usize;
75
76    /// Attempt to decode a byte array to produce an item.
77    /// May return the item with the bytes consumed, a request for more bytes or a parsing error
78    fn decode(out: &[u8]) -> Result<WithSize<Self>, WithOffset<Self::Error>>;
79
80    /// Allocate a byte array of the right size and encode the item in it.
81    fn encode(&self) -> Box<[u8]> {
82        let mut data = vec![0; self.encoded_size()].into_boxed_slice();
83        unsafe { self.encode_in(&mut data) };
84        data
85    }
86}