use crate::Error;
pub struct SkipMissing<I: IntoIterator> {
inner: I::IntoIter,
to_skip: usize,
}
impl<I: IntoIterator> SkipMissing<I> {
pub fn new(inner: I, to_skip: usize) -> Self {
SkipMissing {
inner: inner.into_iter(),
to_skip,
}
}
}
impl<I: IntoIterator<Item = Result<T, Error>>, T> Iterator for SkipMissing<I> {
type Item = Result<T, Error>;
fn next(&mut self) -> Option<Self::Item> {
loop {
let next = self.inner.next()?;
if self.to_skip == 0 {
break Some(next);
} else {
match next {
Ok(x) => break Some(Ok(x)),
Err(Error::BadResponse(reqwest::StatusCode::NOT_FOUND, url)) => {
log::warn!("Missing a manifest: {}", url);
self.to_skip -= 1;
}
Err(e) => break Some(Err(e)),
}
}
}
}
}
pub trait SkipMissingExt: Iterator {
fn skip_missing<T>(self, days: usize) -> SkipMissing<Self>
where
Self: Iterator<Item = Result<T, Error>> + Sized,
{
SkipMissing::new(self, days)
}
}
impl<I: Iterator> SkipMissingExt for I {}