use std::iter::*;
pub struct ZipEnds<I> {
iter: I
}
impl <'a, T, I> Iterator for ZipEnds<I> where
T: 'a,
I: Iterator<Item=&'a T> + DoubleEndedIterator
{
type Item = (&'a T, &'a T);
fn next(&mut self) -> Option<Self::Item> {
let a = self.iter.next();
let b = self.iter.next_back();
match (a, b) {
(Some(a), Some(b)) => Some((a, b)),
(Some(a), _ ) => Some((a, a)),
(_ , Some(b)) => Some((b, b)),
(None , None ) => None
}
}
}
pub trait ZipEndsIterExt: Sized {
type Iter;
fn zip_ends(self) -> ZipEnds<Self::Iter>;
}
impl <'a, T, I, U> ZipEndsIterExt for U where
T: 'a,
I: Iterator<Item=&'a T> + DoubleEndedIterator,
U: IntoIterator<Item=I::Item, IntoIter=I>
{
type Iter = I;
fn zip_ends(self) -> ZipEnds<Self::Iter> {
ZipEnds {
iter: self.into_iter()
}
}
}