byte_transcoder/
reader.rs1use std::convert::TryInto;
2use uuid::Uuid;
3
4use crate::{
5 endian::Endian,
6 reader_error::{ByteReaderError, ByteReaderResult},
7};
8
9#[expect(clippy::module_name_repetitions)]
10pub struct ByteReader<'a> {
11 data: &'a [u8],
12 index: usize,
13 endian: Endian,
14}
15
16impl<'a> ByteReader<'a> {
17 #[must_use]
18 pub fn new(data: &'a [u8], endian: Endian) -> Self {
19 ByteReader {
20 data,
21 index: 0,
22 endian,
23 }
24 }
25
26 pub fn read_u8(&mut self) -> ByteReaderResult<u8> {
30 if self.index >= self.data.len() {
31 return Err(ByteReaderError::NotEnoughBytes {
32 index_offset: self.index,
33 buffer_length: self.data.len(),
34 });
35 }
36
37 let value: u8 = match self.endian {
38 Endian::Little => u8::from_le_bytes([self.data[self.index]]),
39 Endian::Big => u8::from_be_bytes([self.data[self.index]]),
40 };
41 self.index += 1;
42 Ok(value)
43 }
44
45 pub fn read_i8(&mut self) -> ByteReaderResult<i8> {
49 if self.index >= self.data.len() {
50 return Err(ByteReaderError::NotEnoughBytes {
51 index_offset: self.index,
52 buffer_length: self.data.len(),
53 });
54 }
55
56 let value: i8 = match self.endian {
57 Endian::Little => i8::from_le_bytes([self.data[self.index]]),
58 Endian::Big => i8::from_be_bytes([self.data[self.index]]),
59 };
60 self.index += 1;
61 Ok(value)
62 }
63
64 pub fn read_u16(&mut self) -> ByteReaderResult<u16> {
68 let index_offset: usize = self.index + 2;
69 if index_offset > self.data.len() {
70 return Err(ByteReaderError::NotEnoughBytes {
71 index_offset,
72 buffer_length: self.data.len(),
73 });
74 }
75
76 let u16_bytes: [u8; 2] = self.data[self.index..index_offset]
77 .try_into()
78 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
79 let value: u16 = match self.endian {
80 Endian::Little => u16::from_le_bytes(u16_bytes),
81 Endian::Big => u16::from_be_bytes(u16_bytes),
82 };
83 self.index = index_offset;
84 Ok(value)
85 }
86
87 pub fn read_i16(&mut self) -> ByteReaderResult<i16> {
91 let index_offset: usize = self.index + 2;
92 if index_offset > self.data.len() {
93 return Err(ByteReaderError::NotEnoughBytes {
94 index_offset,
95 buffer_length: self.data.len(),
96 });
97 }
98
99 let i16_bytes: [u8; 2] = self.data[self.index..index_offset]
100 .try_into()
101 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
102 let value: i16 = match self.endian {
103 Endian::Little => i16::from_le_bytes(i16_bytes),
104 Endian::Big => i16::from_be_bytes(i16_bytes),
105 };
106 self.index = index_offset;
107 Ok(value)
108 }
109
110 pub fn read_u32(&mut self) -> ByteReaderResult<u32> {
114 let index_offset: usize = self.index + 4;
115 if index_offset > self.data.len() {
116 return Err(ByteReaderError::NotEnoughBytes {
117 index_offset,
118 buffer_length: self.data.len(),
119 });
120 }
121
122 let u32_bytes: [u8; 4] = self.data[self.index..index_offset]
123 .try_into()
124 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
125 let value: u32 = match self.endian {
126 Endian::Little => u32::from_le_bytes(u32_bytes),
127 Endian::Big => u32::from_be_bytes(u32_bytes),
128 };
129 self.index = index_offset;
130 Ok(value)
131 }
132
133 pub fn read_i32(&mut self) -> ByteReaderResult<i32> {
137 let index_offset: usize = self.index + 4;
138 if index_offset > self.data.len() {
139 return Err(ByteReaderError::NotEnoughBytes {
140 index_offset,
141 buffer_length: self.data.len(),
142 });
143 }
144
145 let i32_bytes: [u8; 4] = self.data[self.index..index_offset]
146 .try_into()
147 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
148 let value: i32 = match self.endian {
149 Endian::Little => i32::from_le_bytes(i32_bytes),
150 Endian::Big => i32::from_be_bytes(i32_bytes),
151 };
152 self.index = index_offset;
153 Ok(value)
154 }
155
156 pub fn read_u64(&mut self) -> ByteReaderResult<u64> {
160 let index_offset: usize = self.index + 8;
161 if index_offset > self.data.len() {
162 return Err(ByteReaderError::NotEnoughBytes {
163 index_offset,
164 buffer_length: self.data.len(),
165 });
166 }
167
168 let u64_bytes: [u8; 8] = self.data[self.index..index_offset]
169 .try_into()
170 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
171 let value: u64 = match self.endian {
172 Endian::Little => u64::from_le_bytes(u64_bytes),
173 Endian::Big => u64::from_be_bytes(u64_bytes),
174 };
175 self.index = index_offset;
176 Ok(value)
177 }
178
179 pub fn read_i64(&mut self) -> ByteReaderResult<i64> {
183 let index_offset: usize = self.index + 8;
184 if index_offset > self.data.len() {
185 return Err(ByteReaderError::NotEnoughBytes {
186 index_offset,
187 buffer_length: self.data.len(),
188 });
189 }
190
191 let i64_bytes: [u8; 8] = self.data[self.index..index_offset]
192 .try_into()
193 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
194 let value: i64 = match self.endian {
195 Endian::Little => i64::from_le_bytes(i64_bytes),
196 Endian::Big => i64::from_be_bytes(i64_bytes),
197 };
198 self.index = index_offset;
199 Ok(value)
200 }
201
202 pub fn read_string(&mut self) -> ByteReaderResult<String> {
206 let length: usize = self.read_u8()? as usize;
207 let index_offset: usize = self.index + length;
208 if index_offset > self.data.len() {
209 return Err(ByteReaderError::NotEnoughBytes {
210 index_offset,
211 buffer_length: self.data.len(),
212 });
213 }
214
215 let string_bytes: &[u8] = &self.data[self.index..index_offset];
216 self.index = index_offset;
217 String::from_utf8(string_bytes.to_vec()).map_err(|_| ByteReaderError::InvalidUtf8)
218 }
219
220 pub fn read_uuid(&mut self) -> ByteReaderResult<Uuid> {
224 let index_offset: usize = self.index + 16;
225 if index_offset > self.data.len() {
226 return Err(ByteReaderError::NotEnoughBytes {
227 index_offset,
228 buffer_length: self.data.len(),
229 });
230 }
231
232 let uuid_bytes: [u8; 16] = self.data[self.index..index_offset]
233 .try_into()
234 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
235 self.index = index_offset;
236 Ok(Uuid::from_bytes(uuid_bytes))
237 }
238
239 #[must_use]
240 pub fn read_remaining_bytes(&mut self) -> Vec<u8> {
241 let remaining: Vec<u8> = self.data[self.index..].to_vec();
242 self.index = self.data.len(); remaining
244 }
245
246 #[must_use]
247 pub fn is_empty(&self) -> bool {
248 self.index >= self.data.len()
249 }
250
251 #[must_use]
252 pub fn remaining(&self) -> usize {
253 self.data.len() - self.index
254 }
255}