futures::prelude::stream

Function try_unfold

source
pub fn try_unfold<T, F, Fut, Item>(init: T, f: F) -> TryUnfold<T, F, Fut>
where F: FnMut(T) -> Fut, Fut: TryFuture<Ok = Option<(Item, T)>>,
Expand description

Creates a TryStream from a seed and a closure returning a TryFuture.

This function is the dual for the TryStream::try_fold() adapter: while TryStream::try_fold() reduces a TryStream to one single value, try_unfold() creates a TryStream from a seed value.

try_unfold() will call the provided closure with the provided seed, then wait for the returned TryFuture to complete with (a, b). It will then yield the value a, and use b as the next internal state.

If the closure returns None instead of Some(TryFuture), then the try_unfold() will stop producing items and return Poll::Ready(None) in future calls to poll().

In case of error generated by the returned TryFuture, the error will be returned by the TryStream. The TryStream will then yield Poll::Ready(None) in future calls to poll().

This function can typically be used when wanting to go from the “world of futures” to the “world of streams”: the provided closure can build a TryFuture using other library functions working on futures, and try_unfold() will turn it into a TryStream by repeating the operation.

§Example

use futures::stream::{self, TryStreamExt};

let stream = stream::try_unfold(0, |state| async move {
    if state < 0 {
        return Err(SomeError);
    }

    if state <= 2 {
        let next_state = state + 1;
        let yielded = state * 2;
        Ok(Some((yielded, next_state)))
    } else {
        Ok(None)
    }
});

let result: Result<Vec<i32>, _> = stream.try_collect().await;
assert_eq!(result, Ok(vec![0, 2, 4]));