When implementing both sync and async versions of API in a crate, most API of the two version are almost the same except for some async/await keyword.
maybe-async
help unifying async and sync implementation.
Write async code with normal async
, await
, and let maybe_async
handles
those async
and await
when you need a synchronized code. Switch between
sync and async by toggling is_sync
feature gate.
maybe-async
offers three attribute macros: maybe_async
, must_be_sync
and must_be_async
.
These macros can be applied to trait item, trait impl, function and struct impl.
must_be_async
add async_trait
attribute macro for trait declaration or
implementation to bring async fn support in traits
must_be_sync
convert the async code into sync code by removing all async move
,
async
and await
keyword
maybe_async
offers a unified feature gate to provide sync and async conversion on
demand by feature gate is_sync
.
maybe_async
adopts async first policy.
Add maybe_async
in dependencies with default features means maybe_async
is the same as must_be_async
:
toml
[dependencies]
maybe_async = "0.1"
When specify a is_sync
feature gate, maybe_async
is the same as must_be_sync
:
toml
[dependencies]
maybe_async = { version = "0.1", features = ["is_sync"] }
The async/await language feature alters the async world of rust. Comparing with the map/and_then style, now the async code really resembles sync version code.
```rust
trait A { async fn asyncfnname() -> Result<(), ()> { Ok(()) } fn syncfnname() -> Result<(), ()> { Ok(()) } }
struct Foo;
impl A for Foo { async fn asyncfnname() -> Result<(), ()> { Ok(()) } fn syncfnname() -> Result<(), ()> { Ok(()) } }
async fn maybeasyncfn() -> Result<(), ()> { let a = Foo::asyncfnname().await?;
let b = Foo::sync_fn_name()?;
Ok(())
} ```
When maybe-async
feature gate is_sync
is NOT set, the generated code
is async code:
```rust
trait A { async fn maybeasyncfnname() -> Result<(), ()> { Ok(()) } fn syncfn_name() -> Result<(), ()> { Ok(()) } }
struct Foo;
impl A for Foo { async fn maybeasyncfnname() -> Result<(), ()> { Ok(()) } fn syncfn_name() -> Result<(), ()> { Ok(()) } }
async fn maybeasyncfn() -> Result<(), ()> { let a = Foo::maybeasyncfnname().await?; let b = Foo::syncfn_name()?; Ok(()) } ```
When maybe-async
feature gate is_sync
is set, all async keyword is
ignored and yields a sync version code:
```rust trait A { fn maybeasyncfnname() -> Result<(), ()> { Ok(()) } fn syncfn_name() -> Result<(), ()> { Ok(()) } }
struct Foo;
impl A for Foo { fn maybeasyncfnname() -> Result<(), ()> { Ok(()) } fn syncfn_name() -> Result<(), ()> { Ok(()) } }
fn maybeasyncfn() -> Result<(), ()> { let a = Foo::maybeasyncfnname()?; let b = Foo::syncfn_name()?; Ok(()) } ```