use core::{
marker::PhantomData,
ops::{Deref, DerefMut},
};
use std::collections::VecDeque;
use crate::parser::Parser;
pub struct TokenStream<P, Token, Error>
where
P: Parser<Token, Error>,
{
parser: P,
peeked: VecDeque<Option<Token>>,
error_phantom: PhantomData<Error>,
}
impl<P, Token, Error> TokenStream<P, Token, Error>
where
P: Parser<Token, Error>,
{
pub fn expect(&mut self, expected: Token) -> Result<(), Error> {
P::expect(self, expected)
}
pub fn peek(&mut self) -> Option<&Token> {
self.peek_n(1)[0]
}
pub fn peek_n(&mut self, n: usize) -> Vec<Option<&Token>> {
while self.peeked.len() < n {
self.peeked.push_back(self.parser.next());
}
self.peeked.iter().take(n).map(|opt| opt.as_ref()).collect()
}
pub fn next_n(&mut self, n: usize) -> Vec<Option<Token>> {
let mut result = vec![];
for _ in 0..n {
result.push(self.next());
}
result
}
pub fn require_peek_n(&mut self, n: usize) -> Option<Vec<&Token>> {
while self.peeked.len() < n {
match self.parser.next() {
Some(token) => self.peeked.push_back(Some(token)),
None => return None, }
}
Some(
self.peeked
.iter()
.take(n)
.map(|opt| opt.as_ref().unwrap())
.collect::<Vec<&Token>>(),
)
}
pub fn require_next_n(&mut self, n: usize) -> Option<Vec<Token>> {
let mut result = Vec::new();
for _ in 0..n {
result.push(self.next()?);
}
Some(result)
}
pub fn is_empty(&mut self) -> bool {
self.peek_n(1)[0].is_none()
}
pub fn consume(&mut self, n: usize) {
self.next_n(n);
}
}
impl<P, Token, Error> From<P> for TokenStream<P, Token, Error>
where
P: Parser<Token, Error>,
{
fn from(value: P) -> Self {
Self {
parser: value,
peeked: VecDeque::new(),
error_phantom: PhantomData,
}
}
}
impl<P, Token, Error> Deref for TokenStream<P, Token, Error>
where
P: Parser<Token, Error>,
{
type Target = P;
fn deref(&self) -> &Self::Target {
&self.parser
}
}
impl<P, Token, Error> DerefMut for TokenStream<P, Token, Error>
where
P: Parser<Token, Error>,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.parser
}
}
impl<P, Token, Error> Iterator for TokenStream<P, Token, Error>
where
P: Parser<Token, Error>,
{
type Item = Token;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self.peeked.pop_front() {
Some(v) => v,
None => self.parser.next(),
}
}
}