resiter/onok.rs
1//
2// This Source Code Form is subject to the terms of the Mozilla Public
3// License, v. 2.0. If a copy of the MPL was not distributed with this
4// file, You can obtain one at http://mozilla.org/MPL/2.0/.
5//
6
7#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
8pub struct OnOk<I, O, E, F>(I, F)
9where
10 I: Iterator<Item = Result<O, E>>,
11 F: FnMut(&O);
12
13/// Extension trait for `Iterator<Item = Result<T, E>>` to do something on `Ok(_)`
14pub trait OnOkDo<I, O, E, F>
15where
16 I: Iterator<Item = Result<O, E>>,
17 F: FnMut(&O),
18{
19 /// Perform a side effect on each Ok value
20 ///
21 /// ```
22 /// use resiter::onok::OnOkDo;
23 /// use std::str::FromStr;
24 ///
25 /// let mut oks = Vec::new();
26 /// let _: Vec<Result<usize, ::std::num::ParseIntError>> = ["1", "2", "a", "b", "5"]
27 /// .iter()
28 /// .map(|e| usize::from_str(e))
29 /// .on_ok(|e| oks.push(e.to_owned()))
30 /// .collect();
31 ///
32 /// assert_eq!(oks, vec![1, 2, 5]);
33 /// ```
34 fn on_ok(self, _: F) -> OnOk<I, O, E, F>;
35}
36
37impl<I, O, E, F> OnOkDo<I, O, E, F> for I
38where
39 I: Iterator<Item = Result<O, E>>,
40 F: FnMut(&O),
41{
42 #[inline]
43 fn on_ok(self, f: F) -> OnOk<I, O, E, F> {
44 OnOk(self, f)
45 }
46}
47
48impl<I, O, E, F> Iterator for OnOk<I, O, E, F>
49where
50 I: Iterator<Item = Result<O, E>>,
51 F: FnMut(&O),
52{
53 type Item = Result<O, E>;
54
55 fn next(&mut self) -> Option<Self::Item> {
56 self.0.next().map(|r| {
57 r.map(|o| {
58 (self.1)(&o);
59 o
60 })
61 })
62 }
63}