# bisync

Easily write synchronous and asynchronous code at the same time.

This crate is inspired by [maybe-async](https://github.com/fMeow/maybe-async-rs), but uses a different approach and tries to be more minimalistic.

## How do I use it?
Annotate the functions you'd like to have generic w.r.t. asynchronisity with `#[bisync]`.
You can specialize functions by annotating them with `#[only_sync]` or `#[only_async]`.

You need a tiny bit of boilerplate in the parent module but that's all there is to it.

## Example
```rs
// lib.rs

#[path = "."]
pub mod asynchronous {
    use bisync::asynchronous::*;
    mod inner;
    pub use inner::*;
}

// here you could also add `#[cfg]` attributes to enable or disable this module
#[path = "."]
pub mod blocking {
    use bisync::synchronous::*;
    mod inner;
    pub use inner::*;
}
```

```rs
// inner.rs

// these are all the available definitions:
use super::{bisync, only_sync, only_async, SYNC, ASYNC};
 
#[bisync]
pub async fn foo() -> String {
    bar().await
}
 
#[bisync]
async fn bar() -> String {
    if ASYNC {
        println!("We are in async code.");
    } else if SYNC {
        println!("We are in blocking code.");
    } else {
        panic!("This is neither async nor blocking code but a secret third thing.");
    }
 
    baz().await
}
 
#[only_sync]
fn baz() -> String {
    ureq::get("https://example.com")
        .call()
        .unwrap()
        .into_string()
        .unwrap()
}
 
#[only_async]
async fn baz() -> String {
    reqwest::get("https://example.com")
        .await
        .unwrap()
        .text()
        .await
        .unwrap()
}
```

The example above will strip away all `async` and `await` from the functions in the `blocking` module, but will leave them in the `asynchronous` module.
Hence, you can easily use the functions either in a synchronous or an asynchronous context.
