-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathskip_errors.rs
52 lines (46 loc) · 1.44 KB
/
skip_errors.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use crate::Error;
/// An iterator wrapper to skip missing manifests.
pub struct SkipMissing<I: IntoIterator> {
inner: I::IntoIter,
to_skip: usize,
}
impl<I: IntoIterator> SkipMissing<I> {
/// Create a wrapper.
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)),
}
}
}
}
}
/// An extension trait that adds a `skip_missing` method for iterators.
pub trait SkipMissingExt: Iterator {
/// Skips 404 HTTP errors, but not more than `days` times.
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 {}