1#![warn(missing_docs)]
6#![deny(rustdoc::broken_intra_doc_links)]
7
8use core::cell::Cell;
9
10use super::errors::TBytesError;
11
12#[derive(Clone, Debug)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct TBytesReader<B: TBytesReaderBackend> {
16 backend: B,
17}
18
19impl<B: TBytesReaderBackend> TBytesReader<B> {
20 pub fn new(backend: B) -> Self {
22 Self { backend }
23 }
24}
25
26pub trait TBytesReaderFor<T> {
28 fn read(&self) -> Result<T, TBytesError>;
30 fn read_array<const N: usize>(&self) -> Result<[T; N], TBytesError>;
36}
37
38macro_rules! t_bytes_reader_for {
40 ($type_: ident) => {
41 impl<B: TBytesReaderBackend> TBytesReaderFor<$type_> for TBytesReader<B> {
42 fn read(&self) -> Result<$type_, TBytesError> {
43 const SIZE: usize = core::mem::size_of::<$type_>();
44 let mut bytes = [0u8; SIZE];
45 bytes.copy_from_slice(self.backend.read(SIZE)?);
46
47 Ok($type_::from_le_bytes(bytes))
48 }
49
50 fn read_array<const N: usize>(&self) -> Result<[$type_; N], TBytesError> {
51 const SIZE: usize = core::mem::size_of::<$type_>();
52 let mut result: [$type_; N] = [0 as $type_; N];
53
54 for i in 0..N {
55 let mut bytes = [0u8; SIZE];
56 bytes.copy_from_slice(self.backend.read(SIZE)?);
57 result[i] = $type_::from_le_bytes(bytes);
58 }
59
60 Ok(result)
61 }
62 }
63 };
64}
65
66t_bytes_reader_for!(u8);
68t_bytes_reader_for!(u16);
69t_bytes_reader_for!(u32);
70t_bytes_reader_for!(u64);
71t_bytes_reader_for!(u128);
72t_bytes_reader_for!(i8);
73t_bytes_reader_for!(i16);
74t_bytes_reader_for!(i32);
75t_bytes_reader_for!(i64);
76t_bytes_reader_for!(i128);
77t_bytes_reader_for!(f32);
78t_bytes_reader_for!(f64);
79
80pub trait TBytesReaderBackend {
82 fn read(&self, num_bytes: usize) -> Result<&[u8], TBytesError>;
84}
85
86#[derive(Clone, Debug)]
90#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
91pub struct TBytesReaderSliceBackend<'a> {
92 buffer: &'a [u8],
93 pos: Cell<usize>,
94}
95
96impl<'a> TBytesReaderSliceBackend<'a> {
97 pub fn new(buffer: &'a [u8]) -> Self {
99 Self {
100 buffer,
101 pos: Default::default(),
102 }
103 }
104
105 pub fn pos(&self) -> usize {
107 self.pos.get()
108 }
109}
110
111impl<'a> TBytesReaderBackend for TBytesReaderSliceBackend<'a> {
112 fn read(&self, num_bytes: usize) -> Result<&[u8], TBytesError> {
114 let pos = self.pos.get();
115
116 if self.buffer.len() < pos + num_bytes {
117 return Err(TBytesError::OutOfBounds);
118 }
119
120 let bytes = &self.buffer[pos..pos + num_bytes];
121 self.pos.replace(pos + num_bytes);
122
123 Ok(bytes)
124 }
125}
126
127impl<'a> From<&'a [u8]> for TBytesReader<TBytesReaderSliceBackend<'a>> {
128 fn from(value: &'a [u8]) -> Self {
142 TBytesReader::new(TBytesReaderSliceBackend::new(value))
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn slice_backend() {
152 let buffer = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9u8];
153 let backend = TBytesReaderSliceBackend::new(&buffer);
154
155 assert_eq!(backend.read(2).unwrap(), &[0, 1u8]);
156 assert_eq!(backend.read(4).unwrap(), &[2, 3, 4, 5u8]);
157 assert_eq!(backend.read(4).unwrap(), &[6, 7, 8, 9u8]);
158
159 let eof = backend.read(1);
160 assert!(eof.is_err());
161 assert!(matches!(eof, Err(TBytesError::OutOfBounds)));
162 }
163
164 #[test]
165 fn slice_backend_out_of_bouts_is_idempotent() {
166 let buffer = [42; 10];
167 let backend = TBytesReaderSliceBackend::new(&buffer);
168
169 assert_eq!(backend.read(10).unwrap(), &[42; 10]);
170
171 let eof = backend.read(1);
172 assert!(matches!(eof, Err(TBytesError::OutOfBounds)));
173 let eof = backend.read(1);
174 assert!(matches!(eof, Err(TBytesError::OutOfBounds)));
175
176 assert_eq!(backend.pos(), 10);
177 }
178
179 #[test]
180 fn from_slice() {
181 let buffer = [128, 255, 1, 1u8, 1, 255];
182 let reader = TBytesReader::from(buffer.as_slice());
183
184 let val: u8 = reader.read().unwrap();
185 assert_eq!(val, 128);
186
187 let val: i8 = reader.read().unwrap();
188 assert_eq!(val, -1);
189
190 let val: u16 = reader.read().unwrap();
191 assert_eq!(val, 257);
192
193 let val: [u8; 2] = reader.read_array().unwrap();
194 assert_eq!(val, [1, 255]);
195 }
196
197 #[test]
198 fn bytes_reader_for() {
199 let buffer = [128, 255, 1, 1u8, 1, 255];
200 let backend = TBytesReaderSliceBackend::new(&buffer);
201 let reader = TBytesReader::new(backend);
202
203 let val: u8 = reader.read().unwrap();
204 assert_eq!(val, 128);
205
206 let val: i8 = reader.read().unwrap();
207 assert_eq!(val, -1);
208
209 let val: u16 = reader.read().unwrap();
210 assert_eq!(val, 257);
211
212 let val: [u8; 2] = reader.read_array().unwrap();
213 assert_eq!(val, [1, 255]);
214 }
215
216 #[test]
217 fn arrays() {
218 let buffer = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9u8];
219 let backend = TBytesReaderSliceBackend::new(&buffer);
220 let reader = &TBytesReader::new(backend);
221
222 let result: Result<[u8; 8], TBytesError> = reader.read_array();
223 assert!(result.is_ok());
224 assert_eq!(result.unwrap(), [0, 1, 2, 3, 4, 5, 6, 7u8]);
225
226 let result: Result<[u8; 4], TBytesError> = reader.read_array();
227 assert!(result.is_err());
228 }
229}