use crate::token::Token;
pub trait TokenIterator {
fn next_token(&mut self) -> Result<Token, String>;
#[cfg(test)]
fn equal(mut self, tokens: &[Token]) -> Result<bool, String>
where
Self: Sized,
{
let mut next_token: Token = self.next_token()?;
for token in tokens {
if next_token == Token::Stop || *token != next_token {
return Ok(false);
}
next_token = self.next_token()?;
}
return Ok(next_token == Token::Stop);
}
#[cfg(test)]
fn filter<P>(self, predicat: P) -> FilterToken<Self, P>
where
Self: Sized,
P: Fn(Token) -> bool,
{
return FilterToken::new(self, predicat);
}
}
#[cfg(test)]
pub struct FilterToken<T, P>
where
T: TokenIterator,
P: Fn(Token) -> bool,
{
token_iterator: T,
predicat: P,
}
#[cfg(test)]
impl<T, P> FilterToken<T, P>
where
T: TokenIterator,
P: Fn(Token) -> bool,
{
pub fn new(token_iterator: T, predicat: P) -> Self {
return Self {
token_iterator,
predicat,
};
}
}
#[cfg(test)]
impl<T, P> TokenIterator for FilterToken<T, P>
where
T: TokenIterator,
P: Fn(Token) -> bool,
{
fn next_token(&mut self) -> Result<Token, String> {
let mut token: Token = self.token_iterator.next_token()?;
while !(self.predicat)(token) {
token = self.token_iterator.next_token()?;
}
return Ok(token);
}
}