Rust: Add Iterator that allows "unpoping"

Created on 11 Feb 2018  路  2Comments  路  Source: rust-lang/rust

I am developing a compiler and in order to parse the source code, I must backtrack. To do this I developed an iterator adaptor that stores a list of items to pop off in the future.

Source code:

pub struct PrefixIterator<I: Iterator> {
    iter: I,
    prefix: Vec<I::Item>,
}

impl<I: Iterator> PrefixIterator<I> {
    pub fn new(iter: I) -> Self {
        PrefixIterator {
            iter,
            prefix: Vec::new(),
        }
    }

    pub fn push(&mut self, item: I::Item) {
        self.prefix.push(item);
    }
}

impl<I: Iterator> Iterator for PrefixIterator<I> {
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        if self.prefix.is_empty() {
            self.iter.next()
        } else {
            self.prefix.pop()
        }
    }
}

I called the mechanism of "unpoping" push because of the underlying mechanic. The opposite of next is previous, which isn't appropriate for this context.

Example usage:

let iter = PrefixIterator::new(iter);
match iter.next() {
    Some(';') => {
        iter.push(';');
        return already_parsed_statement;
    },
    Some(c) => {
        ...
    }
    None => (),
}
C-feature-request T-libs

Most helpful comment

I also think you want "unpopping". I think that "unpoping" would be something to do with the Vatican ;-)

All 2 comments

I also think you want "unpopping". I think that "unpoping" would be something to do with the Vatican ;-)

Was this page helpful?
0 / 5 - 0 ratings