Skip to content

Instantly share code, notes, and snippets.

@lovasoa
Created April 16, 2019 07:25
Show Gist options
  • Save lovasoa/2cfddb6de2637dd0ffbb027ee2c89397 to your computer and use it in GitHub Desktop.
Save lovasoa/2cfddb6de2637dd0ffbb027ee2c89397 to your computer and use it in GitHub Desktop.
An iterator that stores the values it yields, in order to be able to access them by index.
/// An iterator where you can look back on items that were already consumed
struct PartiallyConsumedIterator<T, I: Iterator<Item=T>> {
/// Elements that were already consumed
previous: Vec<T>,
/// Elements that still have to be consumed
remaining: I,
}
impl<T, I: Iterator<Item=T>> From<I> for PartiallyConsumedIterator<T, I> {
fn from(iter: I) -> Self {
PartiallyConsumedIterator {
previous: Vec::new(),
remaining: iter,
}
}
}
impl<T, I: Iterator<Item=T>> PartiallyConsumedIterator<T, I> {
fn get(&mut self, index: usize) -> Option<&T> {
let mut i = self.previous.len();
if index < i {
return self.previous.get(index);
}
while let Some(elem) = self.remaining.next() {
self.previous.push(elem);
if i == index {
return self.previous.last();
} else {
i += 1
}
}
None
}
}
#[cfg(test)]
mod tests {
use super::PartiallyConsumedIterator;
#[test]
fn test_iter() {
let mut pci = PartiallyConsumedIterator::from(vec![1, 2, 3].into_iter());
assert_eq!(Some(&1), pci.get(0));
assert_eq!(Some(&2), pci.get(1));
assert_eq!(Some(&3), pci.get(2));
assert_eq!(None, pci.get(3));
assert_eq!(Some(&2), pci.get(1));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment