iter_flow/
map_err.rs

1#[derive(Clone)]
2#[must_use = "iterators are lazy and do nothing unless consumed"]
3pub struct MapErrBy<I, F> {
4    iter: I,
5    f: F,
6}
7
8pub trait MapErrPredicate<E> {
9    type Out;
10    fn call(&mut self, e: E) -> Self::Out;
11}
12
13impl<I, F, T, E> Iterator for MapErrBy<I, F>
14where
15    I: Iterator<Item = Result<T, E>>,
16    F: MapErrPredicate<E>,
17{
18    type Item = Result<T, F::Out>;
19
20    fn next(&mut self) -> Option<Self::Item> {
21        self.iter.next().map(|e| e.map_err(|e| self.f.call(e)))
22    }
23
24    fn size_hint(&self) -> (usize, Option<usize>) {
25        self.iter.size_hint()
26    }
27
28    fn fold<Acc, Fold>(self, init: Acc, mut fold_f: Fold) -> Acc
29    where
30        Self: Sized,
31        Fold: FnMut(Acc, Self::Item) -> Acc,
32    {
33        let mut f = self.f;
34        self.iter
35            .fold(init, move |acc, v| fold_f(acc, v.map_err(|e| f.call(e))))
36    }
37
38    fn collect<B: FromIterator<Self::Item>>(self) -> B
39    where
40        Self: Sized,
41    {
42        let mut f = self.f;
43        self.iter.map(move |v| v.map_err(|e| f.call(e))).collect()
44    }
45}
46
47/// An iterator adaptor that maps the inner error
48///
49/// See [`.map_err()`](crate::Iterflow::map_err) for more information.
50pub type MapErr<I, F> = MapErrBy<I, MapErrFn<F>>;
51
52impl<F, E, O> MapErrPredicate<E> for MapErrFn<F>
53where
54    F: FnMut(E) -> O,
55{
56    type Out = O;
57
58    fn call(&mut self, e: E) -> Self::Out {
59        self.0(e)
60    }
61}
62
63#[derive(Clone)]
64pub struct MapErrFn<F>(F);
65
66/// Create a new `MapErr`.
67pub fn map_err<I, F, E, O>(iter: I, f: F) -> MapErr<I, F>
68where
69    I: Iterator,
70    F: FnMut(E) -> O,
71{
72    MapErr { iter, f: MapErrFn(f) }
73}