#[cfg(test)]
mod tests;
use std::iter::FusedIterator;
pub trait Zip: IntoIterator + Sized {
fn zip_fill<R, F>(self, r: R, fill: F) -> Filler<Self::IntoIter, R::IntoIter, F>
where
R: IntoIterator<Item = Self::Item>,
F: FnMut() -> Self::Item,
{
Filler {
q: self.into_iter(),
r: r.into_iter(),
fill,
}
}
fn zip_fill_default<R>(self, r: R) -> Filler<Self::IntoIter, R::IntoIter, fn() -> Self::Item>
where
R: IntoIterator<Item = Self::Item>,
Self::Item: Default,
{
Filler {
q: self.into_iter(),
r: r.into_iter(),
fill: Self::Item::default,
}
}
fn zip_fill_with<R>(self, r: R, item: Self::Item) -> FillerWith<Self::IntoIter, R::IntoIter>
where
R: IntoIterator<Item = Self::Item>,
Self::Item: Clone,
{
FillerWith {
q: self.into_iter(),
r: r.into_iter(),
item,
}
}
}
impl<I: IntoIterator> Zip for I {}
#[derive(Debug)]
pub struct Filler<Q, R, F>
where
Q: Iterator,
R: Iterator<Item = Q::Item>,
F: FnMut() -> Q::Item,
{
q: Q,
r: R,
fill: F,
}
#[derive(Debug)]
pub struct FillerWith<Q: Iterator, R: Iterator<Item = Q::Item>> {
q: Q,
r: R,
item: Q::Item,
}
impl<Q, R> Iterator for FillerWith<Q, R>
where
Q: Iterator,
R: Iterator<Item = Q::Item>,
Q::Item: Clone,
{
type Item = (Q::Item, Q::Item);
fn next(&mut self) -> Option<Self::Item> {
match (self.q.next(), self.r.next()) {
(None, None) => None,
(Some(q), None) => Some((q, self.item.clone())),
(None, Some(r)) => Some((self.item.clone(), r)),
(Some(q), Some(r)) => Some((q, r)),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
size_hint(self.q.size_hint(), self.r.size_hint())
}
}
impl<Q, R, F> Iterator for Filler<Q, R, F>
where
Q: Iterator,
R: Iterator<Item = Q::Item>,
F: FnMut() -> Q::Item,
{
type Item = (Q::Item, Q::Item);
fn next(&mut self) -> Option<Self::Item> {
match (self.q.next(), self.r.next()) {
(None, None) => None,
(Some(q), None) => Some((q, (self.fill)())),
(None, Some(r)) => Some(((self.fill)(), r)),
(Some(q), Some(r)) => Some((q, r)),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
size_hint(self.q.size_hint(), self.r.size_hint())
}
}
#[inline]
fn size_hint(
(min_a, max_a): (usize, Option<usize>),
(min_b, max_b): (usize, Option<usize>),
) -> (usize, Option<usize>) {
let min = usize::max(min_a, min_b); let max = if let (Some(a), Some(b)) = (max_a, max_b) {
Some(usize::max(a, b))
} else {
None
};
(min, max)
}
impl<Q, R> ExactSizeIterator for FillerWith<Q, R>
where
Q: ExactSizeIterator,
R: ExactSizeIterator<Item = Q::Item>,
Q::Item: Clone,
{}
impl<Q, R> FusedIterator for FillerWith<Q, R>
where
Q: FusedIterator,
R: FusedIterator<Item = Q::Item>,
Q::Item: Clone,
{}
impl<Q, R, F> ExactSizeIterator for Filler<Q, R, F>
where
Q: ExactSizeIterator,
R: ExactSizeIterator<Item = Q::Item>,
F: FnMut() -> Q::Item,
{}
impl<Q, R, F> FusedIterator for Filler<Q, R, F>
where
Q: FusedIterator,
R: FusedIterator<Item = Q::Item>,
F: FnMut() -> Q::Item,
{}