iterator_ext/
try_unfold.rs1use 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}