moore_common/grind/
lookahead.rs

1// Copyright (c) 2016-2021 Fabian Schuiki
2
3use crate::grind::Grinder;
4use std::collections::VecDeque;
5
6pub struct Lookahead<T: Grinder> {
7    inner: T,
8    buffer: VecDeque<T::Item>,
9}
10
11impl<T> Lookahead<T>
12where
13    T: Grinder,
14{
15    pub fn new(inner: T) -> Lookahead<T> {
16        Lookahead {
17            inner: inner,
18            buffer: VecDeque::new(),
19        }
20    }
21
22    pub fn lookahead(&mut self, offset: usize) -> &T::Item {
23        for _ in self.buffer.len()..offset + 1 {
24            self.buffer.push_back(self.inner.next());
25        }
26        &self.buffer[offset]
27    }
28
29    pub fn undo(&mut self, item: T::Item) {
30        self.buffer.push_front(item);
31    }
32}
33
34impl<T> Grinder for Lookahead<T>
35where
36    T: Grinder,
37{
38    type Item = T::Item;
39    type Error = T::Error;
40
41    fn emit(&mut self, err: Self::Error) {
42        self.inner.emit(err)
43    }
44
45    fn next(&mut self) -> Self::Item {
46        match self.buffer.pop_front() {
47            Some(v) => v,
48            None => self.inner.next(),
49        }
50    }
51}
52
53impl<T> From<T> for Lookahead<T>
54where
55    T: Grinder,
56{
57    fn from(inner: T) -> Lookahead<T> {
58        Lookahead::new(inner)
59    }
60}