try_unfold

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 tokio_stream::StreamExt;

#[derive(Debug, PartialEq)]
struct SomeError;

 #[tokio::main]
 async fn main() {
    let stream = tokio_stream_util::try_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)
        }
    });

    assert_eq!(stream.collect::<Vec<_>>().await, vec![Ok(0), Ok(2), Ok(4)]);
}