3 unstable releases
0.2.0 | May 10, 2024 |
---|---|
0.1.1 | May 10, 2024 |
0.1.0 | May 9, 2024 |
#390 in Asynchronous
275 downloads per month
Used in 3 crates
(via asyncs)
150KB
4K
SLoC
async-select
select!
multiplex asynchronous futures simultaneously.
Motivations
Initially, I opened an issue Support multiple async runtimes but not only tokio for zookeeper-client-rust. I saw, there are other projects in community to assist runtime agnostic libraries. Though, I wouldn't say possibly most of they if not all are horrible -:), but I wouldn't they are elegant either. After created spawns, I found that it is actually extremely easy to migrate from tokio runtime for library authors with help from runtime agnostic libraries, say async-io
, async-net
, futures
, futures-rustls
, futures-lite
and etc.. But there are still tokio dependencies in tree, one is select!
, I want to give it a try.
Features
use core::future::ready;
use async_select::select;
#[derive(Default)]
struct FieldStruct {
_a: TupleStruct,
_b: i32,
_c: i32,
}
#[derive(Default)]
struct TupleStruct((), (), ());
// pattern according to syn::Pat
//
// failure will cause compilation error.
async fn patterns() {
select! {
default => {},
complete => {},
// Const(PatConst)
//
// unstable: #![feature(inline_const_pat)] https://github.com/rust-lang/rust/issues/76001
// const { 5 } = ready(5) => {},
// Ident(PatIdent)
mut _v = ready(()) => {},
ref _v = ready(()) => {},
ref mut _v = ready(()) => {},
ref mut _x@FieldStruct{ _b, ..} = ready(FieldStruct::default()) => {},
ref mut _x@FieldStruct{ mut _b, ..} = ready(FieldStruct::default()) => {},
mut _x@FieldStruct{ mut _b, ..} = ready(FieldStruct::default()) => {},
// Lit(PatLit)
5 = ready(5) => {},
// Macro(PatMacro)
// Or(PatOr)
5 | 6 = ready(5) => {},
// Paren(PatParen)
(5 | 6) = ready(5) => {},
// Path(PatPath)
::core::option::Option::None = ready(Some(5)) => {},
::core::option::Option::Some(ref _i) = ready(Some(5)) => {},
// Range(PatRange)
1..=2 = ready(5) => {},
// Reference(PatReference)
//
// This is not supported as we are pattern against value.
// &_v = ready(5) => {}
// &mut _v = ready(5) => {}
// Rest(PatRest)
(ref _i, mut _v, ..) = ready((1, 2, 3, 4)) => {},
// Slice(PatSlice)
//
// Pattern against value but not reference.
// Struct(PatStruct)
FieldStruct { ref mut _a, ref _b, .. } = ready(FieldStruct::default()) => {},
// Tuple(PatTuple)
(1, 2) = ready((1, 2)) => {},
// TupleStruct(PatTupleStruct)
TupleStruct(_a, _b, ..) = ready(TupleStruct::default()) => {},
TupleStruct(ref mut _a, ref _b, ..) = ready(TupleStruct::default()) => {},
// Type(PatType)
// Is this only used in variable definition ?
// Verbatim(TokenStream)
//
// Tokens in pattern position not interpreted by Syn.
// Wild(PatWild)
_ = ready(()) => {}
}
}
Links
- crossbeam-channel: this is where I learned what real marcos look like.
- stuck::select: this is where
async-select::select!
derive from. - futures::select: this is where
default
andcomplete
derive from. - tokio: tokio is great on it own. But it is apprently not kind to runtime agnostic library. You simply can't tell which part of it is runtime agnostic. So better to avoid it entirely if you even want runtime agnostic.
- The Little Book of Rust Macros: hmm, the book.