rust-lang / futures-rs

Zero-cost asynchronous programming in Rust
https://rust-lang.github.io/futures-rs/
Apache License 2.0
5.34k stars 616 forks source link

`async_for!` #2759

Open khoover opened 1 year ago

khoover commented 1 year ago

Searching through past issues didn't turn anything up, but it seems like a killer feature for streams would be, roughly, async for x in stream { ... }. While this doesn't work currently, it seems relatively straightforward to write a macro_rule! for it?

pub fn assert_stream<S: Stream>(s: S) -> S { s }

macro_rules! async_for {
    ($var:ident in $stream:expr, $blk:block) => {
        {
            let mut stream = ::core::pin::pin!(assert_stream($stream));
            while let Some($var) = ::futures::stream::StreamExt::next(&mut stream).await {
                $blk
            }
        }
    }
}

A simple test like

async fn test_async_for<S: Stream<Item = u8>>(mut stream: S) {
    let mut stream = core::pin::pin!(stream); // Commenting this line out makes building fail.
    async_for!(x in stream.by_ref(), {
        println!("{}", x);
        break;
    });
    println!("{:?}", stream.next().await);
}

worked just fine using the macro.

taiki-e commented 1 year ago

Thanks for the proposal.

I don't have a strong opinion on whether futures-rs should include this, since async-stream and others already have the ability to do this.