use std::iter::FusedIterator;
#[derive(Copy, Clone)]
pub struct OutputZipper<I, F> {
inner: I,
func: F,
}
impl<Y, I: ExactSizeIterator, F: Fn(I::Item) -> Y> ExactSizeIterator for OutputZipper<I, F> where
I::Item: Clone
{
}
impl<Y, I: FusedIterator, F: Fn(I::Item) -> Y> FusedIterator for OutputZipper<I, F> where
I::Item: Clone
{
}
impl<Y, I: DoubleEndedIterator, F: Fn(I::Item) -> Y> DoubleEndedIterator for OutputZipper<I, F>
where
I::Item: Clone,
{
fn next_back(&mut self) -> Option<Self::Item> {
if let Some(s) = self.inner.next_back() {
let s2 = s.clone();
Some((s2, (self.func)(s)))
} else {
None
}
}
}
impl<Y, I: Iterator, F: Fn(I::Item) -> Y> Iterator for OutputZipper<I, F>
where
I::Item: Clone,
{
type Item = (I::Item, Y);
fn next(&mut self) -> Option<Self::Item> {
if let Some(s) = self.inner.next() {
let s2 = s.clone();
Some((s2, (self.func)(s)))
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
pub trait OutputZip: Iterator
where
Self::Item: Clone,
{
fn zip_output<Y, F: Fn(Self::Item) -> Y>(self, func: F) -> OutputZipper<Self, F>
where
Self: Sized,
{
OutputZipper { inner: self, func }
}
}
impl<I: Iterator> OutputZip for I where Self::Item: Clone {}