use core::str;
#[derive(Debug)]
pub struct Reader<'a>(&'a [u8]);
impl<'a> Reader<'a> {
pub fn new(buffer: &'a [u8]) -> Self {
Self(buffer)
}
pub fn u8(&mut self) -> Option<u8> {
const SIZE: usize = core::mem::size_of::<u8>();
let value = self.subslice(SIZE)?;
value.first().copied()
}
pub fn u16(&mut self) -> Option<u16> {
const SIZE: usize = core::mem::size_of::<u16>();
let value = self.subslice(SIZE)?;
Some(u16::from_le_bytes(value.get(..SIZE)?.try_into().ok()?))
}
pub fn u32(&mut self) -> Option<u32> {
const SIZE: usize = core::mem::size_of::<u32>();
let value = self.subslice(SIZE)?;
Some(u32::from_le_bytes(value.get(..SIZE)?.try_into().ok()?))
}
pub fn u64(&mut self) -> Option<u64> {
const SIZE: usize = core::mem::size_of::<u64>();
let value = self.subslice(SIZE)?;
Some(u64::from_le_bytes(value.get(..SIZE)?.try_into().ok()?))
}
pub fn u128(&mut self) -> Option<u128> {
const SIZE: usize = core::mem::size_of::<u128>();
let value = self.subslice(SIZE)?;
Some(u128::from_le_bytes(value.get(..SIZE)?.try_into().ok()?))
}
pub fn bytes(&mut self, len: usize) -> Option<&'a [u8]> {
self.subslice(len)?.get(..len)
}
pub fn str(&mut self, len: usize) -> Option<&'a str> {
str::from_utf8(self.bytes(len)?).ok()
}
pub fn reader(&mut self, len: usize) -> Option<Self> {
Some(Self(self.subslice(len)?))
}
pub fn end(&self) -> Option<()> {
self.0.is_empty().then_some(())
}
fn subslice(&mut self, size: usize) -> Option<&'a [u8]> {
if size > self.0.len() {
return None;
}
let (slice, data) = self.0.split_at(size);
self.0 = data;
Some(slice)
}
}