iterator_ext/
try_unfold.rs

1use crate::common::*;
2
3pub fn try_unfold<T, E, St, F>(init: St, f: F) -> TryUnfold<T, E, St, F>
4where
5    F: FnMut(&mut St) -> Result<Option<T>, E>,
6{
7    TryUnfold {
8        state: Some((init, f)),
9        _phantom: PhantomData,
10    }
11}
12
13pub struct TryUnfold<T, E, St, F>
14where
15    F: FnMut(&mut St) -> Result<Option<T>, E>,
16{
17    state: Option<(St, F)>,
18    _phantom: PhantomData<(T, E)>,
19}
20
21impl<T, E, St, F> Iterator for TryUnfold<T, E, St, F>
22where
23    F: FnMut(&mut St) -> Result<Option<T>, E>,
24{
25    type Item = Result<T, E>;
26
27    fn next(&mut self) -> Option<Self::Item> {
28        let (mut state, mut f) = self.state.take()?;
29        let result = f(&mut state).transpose()?;
30
31        if result.is_ok() {
32            self.state = Some((state, f));
33        }
34
35        Some(result)
36    }
37}