This crate exports the macro tokio_select!, which, unlike tokio::select!, can be formatted by rustfmt!
better_tokio_select = "0.2"This macro has all the same capabilities as tokio::select!, but the syntax is slightly different.
tokio::select! takes a list of branches:
<pattern> = <async expression> (, if <precondition>)? => <handler>,Example:
tokio::select! {
Ok(res) = reader.read(&mut buf), if can_read => {
writer.write_all(res.bytes)
}
}tokio_select! takes a match .. expression as an argument, which has a list of arms:
.. if let <pattern> = <async expression> (&& <precondition>)? => <handler>,Example:
tokio_select!(match .. {
.. if let Ok(res) = reader.read(&mut buf) && can_read => {
writer.write_all(res.bytes)
}
})For rustfmt to work, the argument to a macro must be a valid Rust expression. Hence the odd-looking ..s.
Rust compiler expects a pattern in that position, and we provide it with one.
Admittedly, the syntax is a little strange. But it’s also formattable by rustfmt. Trade-offs, people, trade-offs!
tokio::select!:
tokio::select! {
res = reader.read(&mut buf), if can_read => {
let n = res?;
if n == 0 { return Ok(()); }
writer.write_all(&buf[..n]).await?;
}
_ = shutdown.recv() => {
return Ok(());
}
}tokio_select!:
tokio_select!(match .. {
.. if let Ok(n) = reader.read(&mut buf) && can_read => {
let n = res?;
if n == 0 { return Ok(()); }
writer.write_all(&buf[..n]).await?;
}
.. if let _ = shutdown.recv() => {
return Ok(())
}
})tokio::select! {
biased;
Some(Message::Data { id, payload }) = rx.recv() => {
process(id, payload).await;
}
else => {
println!("no messages pending");
tokio::time::sleep(Duration::from_millis(50)).await;
}
}tokio_select!:
tokio_select!(biased, match .. {
.. if let Some(Message::Data { id, payload }) = rx.recv() => {
process(id, payload).await;
}
_ => {
println!("no messages pending");
tokio::time::sleep(Duration::from_millis(50)).await;
}
})More examples are available in the documentation of tokio_select!.
You can make the tokio_select! macro globally available in your crate, without needing to import it, with:
#[macro_use(tokio_select)]
extern crate better_tokio_select;