pub struct SliceReader<'x> {
data: &'x [u8],
pos: usize,
}
impl<'x> SliceReader<'x> {
pub fn new(data: &'x [u8]) -> Self {
Self { data, pos: 0 }
}
pub fn is_empty(&self) -> bool {
self.pos == self.data.len()
}
pub fn len(&self) -> usize {
self.data.len() - self.pos
}
fn advance_by(&mut self, n: usize) {
self.pos += n;
debug_assert!(self.pos <= self.data.len())
}
pub fn read(&mut self, n: usize) -> Option<&'x [u8]> {
if self.len() < n {
return None;
}
let out = &self.data[self.pos..self.pos + n];
self.advance_by(n);
Some(out)
}
pub fn read_one(&mut self) -> Option<u8> {
if self.is_empty() {
return None;
}
let out = self.data[self.pos];
self.advance_by(1);
Some(out)
}
pub fn read_array<const N: usize>(&mut self) -> Option<[u8; N]> {
self.read(N).map(|consumed| consumed.try_into().unwrap())
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
#[test]
fn read_array_works() {
let original = vec![5u8, 7, 234, 2, 45, 0, 12, 32, 192];
let mut reader = SliceReader::new(&original);
assert_eq!(reader.read_array::<3>().unwrap(), [5, 7, 234]);
assert_eq!(reader.len(), 6);
let mut reader = SliceReader::new(&original);
assert_eq!(reader.read_array::<2>().unwrap(), [5, 7]);
assert_eq!(reader.len(), 7);
let mut reader = SliceReader::new(&original);
assert_eq!(reader.read_array::<1>().unwrap(), [5]);
assert_eq!(reader.len(), 8);
let mut reader = SliceReader::new(&original);
assert_eq!(reader.read_array::<0>().unwrap(), []);
assert_eq!(reader.len(), 9);
let mut reader = SliceReader::new(&original);
assert!(reader.read_array::<10>().is_none());
assert_eq!(reader.len(), 9);
let mut reader = SliceReader::new(&original);
assert_eq!(reader.read_array::<2>().unwrap(), [5, 7]);
assert_eq!(reader.read_array::<3>().unwrap(), [234, 2, 45]);
assert_eq!(reader.read_array::<4>().unwrap(), [0, 12, 32, 192]);
assert_eq!(reader.len(), 0);
}
}