A version of async-stream without macros.
This crate provides generic implementations of Stream trait.
Stream is an asynchronous version of std::iter::Iterator.
Two functions are provided - fn_stream and try_fn_stream.
Usage
Basic Usage
If you need to create a stream that may result in error, use try_fn_stream, otherwise use fn_stream.
To create a stream:
- Invoke
fn_streamortry_fn_stream, passing a closure (anonymous function). - Closure will accept an
emitter. To return value from the stream, call.emit(value)onemitterand.awaiton its result. Once stream consumer has processed the value and called.next()on stream,.awaitwill return.
Returning errors
try_fn_stream provides some conveniences for returning errors:
- Errors can be return from closure via
return Err(...)or the question mark (?) operator. This will end the stream. - An
emitteralso has anemit_err()method to return errors without ending the stream.
Limitations
fn_stream does not support cross-task streams, that is all stream values must be produced in the same task as the stream.
Specifically, it is not supported to move StreamEmitter to another thread or tokio task.
If your use case necessitates this, consider using async chanells for that.
Advanced usage
Internal concurrency is supported within fn_stream (see examples/join.rs).
Examples
Finite stream of numbers
use fn_stream;
use Stream;
Read numbers from text file, with error handling
use Context;
use try_fn_stream;
use ;
use ;
Why not async-stream?
async-stream is great! It has a nice syntax, but it is based on macros which brings some flaws:
- proc-macros sometimes interact badly with IDEs such as
rust-analyzerorRustRover. see e.g. https://github.com/rust-lang/rust-analyzer/issues/11533 - proc-macros may increase build times