// Copyright (c) 2016-2021 Fabian Schuiki use crate::grind::Grinder; use std::collections::VecDeque; pub struct Lookahead { inner: T, buffer: VecDeque, } impl Lookahead where T: Grinder, { pub fn new(inner: T) -> Lookahead { Lookahead { inner: inner, buffer: VecDeque::new(), } } pub fn lookahead(&mut self, offset: usize) -> &T::Item { for _ in self.buffer.len()..offset + 1 { self.buffer.push_back(self.inner.next()); } &self.buffer[offset] } pub fn undo(&mut self, item: T::Item) { self.buffer.push_front(item); } } impl Grinder for Lookahead where T: Grinder, { type Item = T::Item; type Error = T::Error; fn emit(&mut self, err: Self::Error) { self.inner.emit(err) } fn next(&mut self) -> Self::Item { match self.buffer.pop_front() { Some(v) => v, None => self.inner.next(), } } } impl From for Lookahead where T: Grinder, { fn from(inner: T) -> Lookahead { Lookahead::new(inner) } }