use crate::peeking::{Peeking, PeekingIter};
pub struct Parser<I>
where
I: Iterator,
{
peeking: PeekingIter<I>,
line: u16,
col: u16,
}
impl<I: Iterator<Item = char> + Clone> Peeking for Parser<I> {
fn peek(&mut self) -> Option<Self::Item> {
self.peeking.peek()
}
fn rewind_peeking(&mut self) {
self.peeking.rewind_peeking();
}
fn advance_to_peeked(&mut self) {
self.peeking.advance_to_peeked();
}
}
impl<I: Iterator<Item = char> + Clone> Parser<I> {
pub fn new(iter: I) -> Self {
Self {
peeking: PeekingIter::new(iter),
line: 1,
col: 0,
}
}
pub fn next(&mut self) -> Option<char> {
let next = self.peeking.next();
match next {
None => (),
Some('\n') => {
self.line += 1;
self.col = 0;
}
_ => {
self.col += 1;
}
}
next
}
pub fn into_inner(self) -> I {
PeekingIter::into_inner(self.peeking)
}
pub fn line(&self) -> u16 {
self.line
}
pub fn col(&self) -> u16 {
self.col
}
}
impl<I: Iterator<Item = char> + Clone> Iterator for Parser<I> {
type Item = char;
fn next(&mut self) -> Option<char> {
Parser::next(self)
}
}
#[cfg(test)]
mod tests {
use crate::parser::Parser;
use crate::peeking::Peeking;
fn next_while() {
let mut it = Parser::new("ABc".chars());
assert_eq!(
it.next_while(|c| c.is_uppercase()),
"AB".chars().collect::<Vec<_>>()
);
assert_eq!(it.peek(), Some('c'));
assert_eq!(it.next(), Some('c'));
}
}