Is there an Iterator
, either in std
or a maintained crate, that repeats the first and last element of another Iterator
given Item
is Clone
?
Example:
let iter = [1, 2, 3].into_iter();
assert!(iter.repeat_first_and_last().eq([1, 1, 2, 3, 3]));
I ended up rolling my own.
use std::{mem::take, iter::Fuse};
use tap::Tap;
struct Padded<T: Iterator> {
inner: Fuse<T>,
repeat_first: bool,
repeat_last: bool,
next: Option<T::Item>,
}
impl<T: Iterator> Padded<T>
where
T::Item: Clone,
{
fn new(inner: impl IntoIterator<IntoIter = T>) -> Self
where
T::Item: Clone,
{
let mut inner = inner.into_iter().fuse();
let next = inner.next();
Self { inner, next, repeat_first: true, repeat_last: true, }
}
}
impl<T: Iterator> Iterator for Padded<T>
where
T::Item: Clone,
{
type Item = T::Item;
fn next(&mut self) -> Option<Self::Item> {
self.next.take().tap(|next| {
if take(&mut self.repeat_first) {
self.next = next.clone();
} else {
self.next = self.inner.next().or_else(|| {
next.as_ref().filter(|_| take(&mut self.repeat_last)).cloned()
})
}
})
}
}
fn main() {
Padded::new([1, 2, 3]).for_each(|n| print!("{n}"));
}