iterator-ext 0.2.1

An extension to Rust's Iterator
Documentation
use crate::common::*;

pub fn try_unfold<T, E, St, F>(init: St, f: F) -> TryUnfold<T, E, St, F>
where
    F: FnMut(&mut St) -> Result<Option<T>, E>,
{
    TryUnfold {
        state: Some((init, f)),
        _phantom: PhantomData,
    }
}

pub struct TryUnfold<T, E, St, F>
where
    F: FnMut(&mut St) -> Result<Option<T>, E>,
{
    state: Option<(St, F)>,
    _phantom: PhantomData<(T, E)>,
}

impl<T, E, St, F> Iterator for TryUnfold<T, E, St, F>
where
    F: FnMut(&mut St) -> Result<Option<T>, E>,
{
    type Item = Result<T, E>;

    fn next(&mut self) -> Option<Self::Item> {
        let (mut state, mut f) = self.state.take()?;
        let result = f(&mut state).transpose()?;

        if result.is_ok() {
            self.state = Some((state, f));
        }

        Some(result)
    }
}