use crate::asm_core;
#[derive(Debug)]
pub struct Stream<'a, T> {
pub idx: usize,
data: &'a [T],
}
impl<'a, T: Copy> Stream<'a, T> {
#[inline]
pub fn current_cpy(&self) -> Option<T> {
self.data.get(self.idx).copied()
}
}
impl<'a, T: Eq + Copy> Stream<'a, T> {
#[inline]
pub fn expect_and_skip(&mut self, expect: T) -> Option<T> {
let c = self.current_cpy()?;
if c == expect {
self.advance();
Some(c)
} else {
None
}
}
}
impl<'a, T> Stream<'a, T> {
#[inline]
pub fn new(data: &'a [T]) -> Stream<'a, T> {
Self { data, idx: 0 }
}
#[inline]
pub fn len(&self) -> usize {
self.data.len()
}
#[inline]
pub fn data(&self) -> &[T] {
self.data
}
#[inline]
pub fn advance(&mut self) {
self.idx += 1;
}
#[inline]
pub fn advance_by(&mut self, step: usize) {
self.idx += step;
}
#[allow(dead_code)]
#[inline]
pub fn is_eof(&self) -> bool {
asm_core::usize_ge(self.idx, self.data.len())
}
#[inline]
pub fn slice(&self, from: usize, to: usize) -> &'a [T] {
&self.data[from..to]
}
#[inline]
pub fn slice_checked(&self, from: usize, to: usize) -> &'a [T] {
&self.data[from..asm_core::usize_min(self.data.len(), to)]
}
#[inline]
pub fn slice_len(&self, from: usize, len: usize) -> &'a [T] {
self.slice_checked(from, asm_core::usize_add(self.idx, len))
}
}