stream_generator is an alternative to async-stream and genawaiter.
It allows you to create a stream from a generator function:
use futures::{stream::StreamExt, Stream};
use stream_generator::generate_stream;
fn my_stream(start: u32) -> impl Stream<Item=u32> {
generate_stream(move |mut y| async move {
for i in start.. {
y.send(i).await;
if i == 45 {
break;
}
}
})
}
#[tokio::main]
async fn main() {
let values: Vec<_> = my_stream(42).collect().await;
assert_eq!(values, vec![42, 43, 44, 45]);
}
There is also Result
-friendly generate_try_stream helper.
Key features:
- Very simple, safe-only implementation which only depends on the
futures
crate; - No macros and no unstable syntax, so the code is easy to understand, doesn't clash with other macros, and rustfmt works on it;
- The yielder is a proper public type, so a complex generator function can be easily split into multiple functions receiving the yielder as an argument.
-
generate_try_stream
allows you to explicitly yield bothOk
andErr
values, and the stream doesn't have to end after yielding anErr
item.