use crate::errors::{ParseError, ParseResult};
use crate::scanner::Scanner;
use crate::visitor::Visitor;
#[derive(Debug)]
pub struct Acceptor<'a, 'b, T, V> {
data: Option<V>,
scanner: &'b mut Scanner<'a, T>,
}
impl<'a, 'b, T, V> Acceptor<'a, 'b, T, V> {
pub fn new(scanner: &'b mut Scanner<'a, T>) -> Acceptor<'a, 'b, T, V> {
Acceptor {
data: None,
scanner,
}
}
}
impl<'a, T, V> Acceptor<'a, '_, T, V> {
pub fn try_or<U: Visitor<'a, T>, F>(mut self, transformer: F) -> ParseResult<Self>
where
F: Fn(U) -> V,
{
let cursor = self.scanner.current_position();
if self.data.is_some() {
return Ok(self);
}
match U::accept(self.scanner) {
Ok(found) => {
self.data = Some(transformer(found));
}
Err(ParseError::UnexpectedToken | ParseError::UnexpectedEndOfInput) => {
self.scanner.jump_to(cursor);
}
Err(err) => {
return Err(err);
}
}
Ok(self)
}
pub fn finish(self) -> Option<V> {
self.data
}
}