byte_transcoder/
reader.rs1use std::convert::TryInto;
2use uuid::Uuid;
3
4use crate::reader_error::{ByteReaderError, ByteReaderResult};
5
6#[expect(clippy::module_name_repetitions)]
7pub struct ByteReader<'a> {
8 data: &'a [u8],
9 index: usize,
10}
11
12impl<'a> ByteReader<'a> {
13 #[must_use]
14 pub fn new(data: &'a [u8]) -> Self {
15 ByteReader { data, index: 0 }
16 }
17
18 pub fn read_u8(&mut self) -> ByteReaderResult<u8> {
22 if self.index >= self.data.len() {
23 return Err(ByteReaderError::NotEnoughBytes {
24 index_offset: self.index,
25 buffer_length: self.data.len(),
26 });
27 }
28
29 let value: u8 = self.data[self.index];
30 self.index += 1;
31 Ok(value)
32 }
33
34 pub fn read_u16(&mut self) -> ByteReaderResult<u16> {
38 let index_offset: usize = self.index + 2;
39 if index_offset > self.data.len() {
40 return Err(ByteReaderError::NotEnoughBytes {
41 index_offset,
42 buffer_length: self.data.len(),
43 });
44 }
45
46 let u16_bytes: [u8; 2] = self.data[self.index..index_offset]
47 .try_into()
48 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
49 let value: u16 = u16::from_le_bytes(u16_bytes);
50 self.index = index_offset;
51 Ok(value)
52 }
53
54 pub fn read_u32(&mut self) -> ByteReaderResult<u32> {
58 let index_offset: usize = self.index + 4;
59 if index_offset > self.data.len() {
60 return Err(ByteReaderError::NotEnoughBytes {
61 index_offset,
62 buffer_length: self.data.len(),
63 });
64 }
65
66 let u32_bytes: [u8; 4] = self.data[self.index..index_offset]
67 .try_into()
68 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
69 let value: u32 = u32::from_le_bytes(u32_bytes);
70 self.index = index_offset;
71 Ok(value)
72 }
73
74 pub fn read_u64(&mut self) -> ByteReaderResult<u64> {
78 let index_offset: usize = self.index + 8;
79 if index_offset > self.data.len() {
80 return Err(ByteReaderError::NotEnoughBytes {
81 index_offset,
82 buffer_length: self.data.len(),
83 });
84 }
85
86 let u64_bytes: [u8; 8] = self.data[self.index..index_offset]
87 .try_into()
88 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
89 let value: u64 = u64::from_le_bytes(u64_bytes);
90 self.index = index_offset;
91 Ok(value)
92 }
93
94 pub fn read_string(&mut self) -> ByteReaderResult<String> {
98 let length: usize = self.read_u8()? as usize;
99 let index_offset: usize = self.index + length;
100 if index_offset > self.data.len() {
101 return Err(ByteReaderError::NotEnoughBytes {
102 index_offset,
103 buffer_length: self.data.len(),
104 });
105 }
106
107 let string_bytes: &[u8] = &self.data[self.index..index_offset];
108 self.index = index_offset;
109 String::from_utf8(string_bytes.to_vec()).map_err(|_| ByteReaderError::InvalidUtf8)
110 }
111
112 pub fn read_uuid(&mut self) -> ByteReaderResult<Uuid> {
116 let index_offset: usize = self.index + 16;
117 if index_offset > self.data.len() {
118 return Err(ByteReaderError::NotEnoughBytes {
119 index_offset,
120 buffer_length: self.data.len(),
121 });
122 }
123
124 let uuid_bytes: [u8; 16] = self.data[self.index..index_offset]
125 .try_into()
126 .map_err(|_| ByteReaderError::SliceConversionFailure)?;
127 self.index = index_offset;
128 Ok(Uuid::from_bytes(uuid_bytes))
129 }
130
131 #[must_use]
132 pub fn read_remaining_bytes(&mut self) -> Vec<u8> {
133 let remaining: Vec<u8> = self.data[self.index..].to_vec();
134 self.index = self.data.len(); remaining
136 }
137
138 #[must_use]
139 pub fn is_empty(&self) -> bool {
140 self.index >= self.data.len()
141 }
142
143 #[must_use]
144 pub fn remaining(&self) -> usize {
145 self.data.len() - self.index
146 }
147}