pub struct Cursor<'src> {
src: &'src [u8],
pos: usize,
}
impl<'src> Cursor<'src> {
pub fn new(src: &'src [u8]) -> Self {
Self { src, pos: 0 }
}
pub fn pos(&self) -> usize {
self.pos
}
pub fn is_eof(&self) -> bool {
self.pos >= self.src.len()
}
pub fn peek(&self) -> Option<u8> {
self.src.get(self.pos).copied()
}
pub fn peek_nth(&self, n: usize) -> Option<u8> {
self.src.get(self.pos + n).copied()
}
pub fn advance(&mut self) -> Option<u8> {
let b = self.src.get(self.pos).copied()?;
self.pos += 1;
Some(b)
}
pub fn skip(&mut self, n: usize) {
self.pos = (self.pos + n).min(self.src.len());
}
pub fn eat_while(&mut self, predicate: impl Fn(u8) -> bool) {
while let Some(b) = self.peek() {
if predicate(b) {
self.pos += 1;
} else {
break;
}
}
}
pub fn slice_from(&self, start: usize) -> &'src [u8] {
&self.src[start..self.pos]
}
pub fn starts_with(&self, needle: &[u8]) -> bool {
self.src[self.pos..].starts_with(needle)
}
pub fn remaining(&self) -> &'src [u8] {
&self.src[self.pos..]
}
}