Maybe-Async Procedure Macro

Build Status MIT licensed Latest Version maybe-async

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.

Key features

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.

Motivation

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.

Examples

```rust

[maybe_async]

trait A { async fn asyncfnname() -> Result<(), ()> { Ok(()) } fn syncfnname() -> Result<(), ()> { Ok(()) } }

struct Foo;

[maybe_async]

impl A for Foo { async fn asyncfnname() -> Result<(), ()> { Ok(()) } fn syncfnname() -> Result<(), ()> { Ok(()) } }

[maybe_async]

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

[async_trait]

trait A { async fn maybeasyncfnname() -> Result<(), ()> { Ok(()) } fn syncfn_name() -> Result<(), ()> { Ok(()) } }

struct Foo;

[async_trait]

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(()) } ```