use std::{iter::from_fn, vec::IntoIter};
use super::{Len, Op, Seq};
pub struct Iter<T, A> {
iter: IntoIter<Op<T, A>>,
partial: Option<Op<T, A>>,
}
impl<T, A> Iter<T, A>
where
T: Clone + Default + Seq,
A: Clone + Default,
{
pub(crate) fn new(iter: IntoIter<Op<T, A>>) -> Iter<T, A> {
Iter {
iter,
partial: Default::default(),
}
}
pub fn next_mut(&mut self) -> Option<&mut Op<T, A>> {
match &self.partial {
Some(partial) if partial.len() > 0 => self.partial.as_mut(),
Some(_) | None => {
self.partial = self.iter.next();
self.partial.as_mut()
}
}
}
pub fn zip_mut<'a, F, U>(
&'a mut self,
other: &'a mut Iter<T, A>,
map_fn: F,
) -> impl Iterator<Item = U> + 'a
where
F: for<'b> Fn(&'b mut Op<T, A>, &'b mut Op<T, A>) -> U + 'a,
{
from_fn(move || match (self.next_mut(), other.next_mut()) {
(Some(self_op), Some(other_op)) => Some(map_fn(self_op, other_op)),
_ => None,
})
}
}
impl<T, A> Iterator for Iter<T, A>
where
T: Default + Seq,
A: Default,
{
type Item = Op<T, A>;
fn next(&mut self) -> Option<Self::Item> {
match self.partial.take() {
Some(partial) if partial.len() > 0 => Some(partial),
Some(_) | None => self.iter.next(),
}
}
}