usesuper::assert_stream; usecrate::unfold_state::UnfoldState; use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project;
/// Creates a `Stream` from a seed and a closure returning a `Future`. /// /// This function is the dual for the `Stream::fold()` adapter: while /// `Stream::fold()` reduces a `Stream` to one single value, `unfold()` creates a /// `Stream` from a seed value. /// /// `unfold()` will call the provided closure with the provided seed, then wait /// for the returned `Future` 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(Future)`, then the `unfold()` /// will stop producing items and return `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 /// `Future` using other library functions working on futures, and `unfold()` /// will turn it into a `Stream` by repeating the operation. /// /// # Example /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::unfold(0, |state| async move { /// if state <= 2 { /// let next_state = state + 1; /// let yielded = state * 2; /// Some((yielded, next_state)) /// } else { /// None /// } /// }); /// /// let result = stream.collect::<Vec<i32>>().await; /// assert_eq!(result, vec![0, 2, 4]); /// # }); /// ``` pubfn unfold<T, F, Fut, Item>(init: T, f: F) -> Unfold<T, F, Fut> where
F: FnMut(T) -> Fut,
Fut: Future<Output = Option<(Item, T)>>,
{
assert_stream::<Item, _>(Unfold { f, state: UnfoldState::Value { value: init } })
}
pin_project! { /// Stream for the [`unfold`] function. #[must_use = "streams do nothing unless polled"] pubstruct Unfold<T, F, Fut> {
f: F, #[pin]
state: UnfoldState<T, Fut>,
}
}
let step = match this.state.as_mut().project_future() {
Some(fut) => ready!(fut.poll(cx)),
None => panic!("Unfold must not be polled after it returned `Poll::Ready(None)`"),
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.