use super::{Deserializable, DeserializationError, Vec};
pub trait ByteReader {
fn read_u8(&mut self) -> Result<u8, DeserializationError>;
fn peek_u8(&self) -> Result<u8, DeserializationError>;
fn read_vec(&mut self, len: usize) -> Result<Vec<u8>, DeserializationError>;
fn read_array<const N: usize>(&mut self) -> Result<[u8; N], DeserializationError>;
fn check_eor(&self, num_bytes: usize) -> Result<(), DeserializationError>;
fn has_more_bytes(&self) -> bool;
fn read_bool(&mut self) -> Result<bool, DeserializationError> {
let byte = self.read_u8()?;
match byte {
0 => Ok(false),
1 => Ok(true),
_ => Err(DeserializationError::InvalidValue(format!(
"{byte} is not a boolean value"
))),
}
}
fn read_u16(&mut self) -> Result<u16, DeserializationError> {
let bytes = self.read_array::<2>()?;
Ok(u16::from_le_bytes(bytes))
}
fn read_u32(&mut self) -> Result<u32, DeserializationError> {
let bytes = self.read_array::<4>()?;
Ok(u32::from_le_bytes(bytes))
}
fn read_u64(&mut self) -> Result<u64, DeserializationError> {
let bytes = self.read_array::<8>()?;
Ok(u64::from_le_bytes(bytes))
}
fn read_u128(&mut self) -> Result<u128, DeserializationError> {
let bytes = self.read_array::<16>()?;
Ok(u128::from_le_bytes(bytes))
}
fn read<D>(&mut self) -> Result<D, DeserializationError>
where
Self: Sized,
D: Deserializable,
{
D::read_from(self)
}
}
pub struct SliceReader<'a> {
source: &'a [u8],
pos: usize,
}
impl<'a> SliceReader<'a> {
pub fn new(source: &'a [u8]) -> Self {
SliceReader { source, pos: 0 }
}
}
impl<'a> ByteReader for SliceReader<'a> {
fn read_u8(&mut self) -> Result<u8, DeserializationError> {
self.check_eor(1)?;
let result = self.source[self.pos];
self.pos += 1;
Ok(result)
}
fn peek_u8(&self) -> Result<u8, DeserializationError> {
self.check_eor(1)?;
Ok(self.source[self.pos])
}
fn read_vec(&mut self, len: usize) -> Result<Vec<u8>, DeserializationError> {
self.check_eor(len)?;
let result = self.source[self.pos..self.pos + len].to_vec();
self.pos += len;
Ok(result)
}
fn read_array<const N: usize>(&mut self) -> Result<[u8; N], DeserializationError> {
self.check_eor(N)?;
let mut result = [0_u8; N];
result.copy_from_slice(&self.source[self.pos..self.pos + N]);
self.pos += N;
Ok(result)
}
fn check_eor(&self, num_bytes: usize) -> Result<(), DeserializationError> {
if self.pos + num_bytes > self.source.len() {
return Err(DeserializationError::UnexpectedEOF);
}
Ok(())
}
fn has_more_bytes(&self) -> bool {
self.pos < self.source.len()
}
}