numbat_codec/
nested_de_input.rs

1pub use crate::codec_err::DecodeError;
2
3/// Trait that allows reading of data into a slice.
4pub trait NestedDecodeInput {
5    /// The remaining length of the input data.
6    fn remaining_len(&mut self) -> usize;
7
8    fn empty(&mut self) -> bool {
9        self.remaining_len() == 0
10    }
11
12    /// Read the exact number of bytes required to fill the given buffer.
13    fn read_into(&mut self, into: &mut [u8]) -> Result<(), DecodeError>;
14
15    /// Read the exact number of bytes required to fill the given buffer.
16    /// Exit early if there are not enough bytes to fill the result.
17    fn read_into_or_exit<ExitCtx: Clone>(
18        &mut self,
19        into: &mut [u8],
20        c: ExitCtx,
21        exit: fn(ExitCtx, DecodeError) -> !,
22    );
23
24    /// Read a single byte from the input.
25    fn read_byte(&mut self) -> Result<u8, DecodeError> {
26        let mut buf = [0u8];
27        self.read_into(&mut buf[..])?;
28        Ok(buf[0])
29    }
30
31    /// Read a single byte from the input.
32    fn read_byte_or_exit<ExitCtx: Clone>(
33        &mut self,
34        c: ExitCtx,
35        exit: fn(ExitCtx, DecodeError) -> !,
36    ) -> u8 {
37        let mut buf = [0u8];
38        self.read_into_or_exit(&mut buf[..], c, exit);
39        buf[0]
40    }
41
42    /// Read the exact number of bytes required to fill the given buffer.
43    fn read_slice(&mut self, length: usize) -> Result<&[u8], DecodeError>;
44
45    /// Read the exact number of bytes required to fill the given buffer.
46    /// Exit directly if the input contains too few bytes.
47    fn read_slice_or_exit<ExitCtx: Clone>(
48        &mut self,
49        length: usize,
50        c: ExitCtx,
51        exit: fn(ExitCtx, DecodeError) -> !,
52    ) -> &[u8];
53
54    /// Clears the input buffer and returns all remaining bytes.
55    fn flush(&mut self) -> &[u8];
56}
57
58impl<'a> NestedDecodeInput for &'a [u8] {
59    fn remaining_len(&mut self) -> usize {
60        self.len()
61    }
62
63    fn read_into(&mut self, into: &mut [u8]) -> Result<(), DecodeError> {
64        if into.len() > self.len() {
65            return Err(DecodeError::INPUT_TOO_SHORT);
66        }
67        let len = into.len();
68        into.copy_from_slice(&self[..len]);
69        *self = &self[len..];
70        Ok(())
71    }
72
73    fn read_into_or_exit<ExitCtx: Clone>(
74        &mut self,
75        into: &mut [u8],
76        c: ExitCtx,
77        exit: fn(ExitCtx, DecodeError) -> !,
78    ) {
79        if into.len() > self.len() {
80            exit(c, DecodeError::INPUT_TOO_SHORT);
81        }
82        let len = into.len();
83        into.copy_from_slice(&self[..len]);
84        *self = &self[len..];
85    }
86
87    fn read_slice(&mut self, length: usize) -> Result<&[u8], DecodeError> {
88        if length > self.len() {
89            return Err(DecodeError::INPUT_TOO_SHORT);
90        }
91
92        let (result, rest) = self.split_at(length);
93        *self = rest;
94        Ok(result)
95    }
96
97    fn read_slice_or_exit<ExitCtx: Clone>(
98        &mut self,
99        length: usize,
100        c: ExitCtx,
101        exit: fn(ExitCtx, DecodeError) -> !,
102    ) -> &[u8] {
103        if length > self.len() {
104            exit(c, DecodeError::INPUT_TOO_SHORT);
105        }
106
107        let (result, rest) = self.split_at(length);
108        *self = rest;
109        result
110    }
111
112    fn flush(&mut self) -> &[u8] {
113        let result = &self[..];
114        *self = &[];
115        result
116    }
117}