use std::collections::VecDeque;
use std::vec::IntoIter;
struct PeekingTakeWhile<'a, T, P>
where
T: Clone + 'a,
P: Fn(&T) -> bool,
{
peeker: &'a mut PeekIter<T>,
predicate: P,
}
impl<'a, T, P> Iterator for PeekingTakeWhile<'a, T, P>
where
T: Clone + 'a,
P: Fn(&T) -> bool,
{
type Item = T;
fn next(&mut self) -> Option<T> {
if let Some(v) = self.peeker.peek() {
if (self.predicate)(&v) {
return self.peeker.next();
}
}
None
}
}
pub struct PeekIter<T>
where
T: Clone,
{
iter: IntoIter<T>,
lookahead: VecDeque<Option<T>>,
}
impl<T> PeekIter<T>
where
T: Clone,
{
pub fn new(iter: IntoIter<T>) -> Self {
let mut lookahead = VecDeque::new();
lookahead.reserve(5);
Self { iter, lookahead }
}
pub fn peek(&mut self) -> Option<&T> {
if self.lookahead.is_empty() {
let next = self.iter.next();
self.lookahead.push_back(next);
}
self.lookahead[0].as_ref()
}
pub fn peek_map_n<R>(&mut self, n: usize, f: fn(&T) -> R) -> VecDeque<R> {
while self.lookahead.len() < n {
let next = self.iter.next();
self.lookahead.push_back(next);
}
self.lookahead
.iter()
.take(n)
.filter_map(|o| o.as_ref())
.map(f)
.collect()
}
pub fn push_front(&mut self, item: T) {
self.lookahead.push_front(Some(item));
}
}
impl<T> Iterator for PeekIter<T>
where
T: Clone,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.lookahead
.pop_front()
.unwrap_or_else(|| self.iter.next())
}
}