use crate::errors::ParseResult;
use crate::visitor::Visitor;
use std::io::Cursor;
use std::ops::Deref;
#[derive(Debug, PartialEq, Clone)]
pub struct Scanner<'a, T> {
cursor: Cursor<&'a [T]>,
}
impl<'a, T> Scanner<'a, T> {
pub fn new(data: &'a [T]) -> Scanner<'a, T> {
Scanner {
cursor: Cursor::new(data),
}
}
}
impl<'a, T> Scanner<'a, T> {
pub fn bump_by(&mut self, n: usize) {
self.cursor.set_position(self.cursor.position() + n as u64);
}
pub fn jump_to(&mut self, n: usize) {
self.cursor.set_position(n as u64);
}
pub fn rewind(&mut self, n: usize) {
self.cursor.set_position(self.cursor.position() - n as u64);
}
pub fn current_position(&self) -> usize {
self.cursor.position() as usize
}
pub fn remaining(&self) -> &'a [T] {
&self.cursor.get_ref()[self.current_position()..]
}
pub fn data(&self) -> &'a [T] {
self.cursor.get_ref()
}
pub fn is_empty(&self) -> bool {
self.remaining().is_empty()
}
}
impl<'a, T> Deref for Scanner<'a, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
self.remaining()
}
}
impl<'a, T> Scanner<'a, T> {
pub fn visit<V: Visitor<'a, T>>(&mut self) -> ParseResult<V> {
V::accept(self)
}
}