use crate::{no_panic, Input};
pub struct Reader<'a> {
input: no_panic::Slice<'a>,
i: usize,
}
impl core::fmt::Debug for Reader<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Reader").finish()
}
}
impl<'a> Reader<'a> {
#[inline]
pub fn new(input: Input<'a>) -> Self {
Self {
input: input.into_value(),
i: 0,
}
}
#[inline]
pub fn at_end(&self) -> bool {
self.i == self.input.len()
}
#[inline]
pub fn peek(&self, b: u8) -> bool {
match self.input.get(self.i) {
Some(actual_b) => b == *actual_b,
None => false,
}
}
#[inline]
pub fn read_byte(&mut self) -> Result<u8, EndOfInput> {
match self.input.get(self.i) {
Some(b) => {
self.i += 1; Ok(*b)
}
None => Err(EndOfInput),
}
}
#[inline]
pub fn read_bytes(&mut self, num_bytes: usize) -> Result<Input<'a>, EndOfInput> {
let new_i = self.i.checked_add(num_bytes).ok_or(EndOfInput)?;
let ret = self
.input
.subslice(self.i..new_i)
.map(From::from)
.ok_or(EndOfInput)?;
self.i = new_i;
Ok(ret)
}
#[inline]
pub fn read_bytes_to_end(&mut self) -> Input<'a> {
let to_skip = self.input.len() - self.i;
self.read_bytes(to_skip).unwrap()
}
pub fn read_partial<F, R, E>(&mut self, read: F) -> Result<(Input<'a>, R), E>
where
F: FnOnce(&mut Reader<'a>) -> Result<R, E>,
{
let start = self.i;
let r = read(self)?;
let bytes_read = self.input.subslice(start..self.i).unwrap().into();
Ok((bytes_read, r))
}
#[inline]
pub fn skip(&mut self, num_bytes: usize) -> Result<(), EndOfInput> {
self.read_bytes(num_bytes).map(|_| ())
}
#[inline]
pub fn skip_to_end(&mut self) {
let _ = self.read_bytes_to_end();
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct EndOfInput;