gemini
An attribute proc macro that lets a user choose a sync or async API with no overhead maintenance burden.
One of the frustrations I have is not getting to choose whether the code or APIs
I work with is sync or async. The same goes for writing a library as it should
be up to the caller to choose. The problem with this is that it makes it hard to
maintain with conditional compilation and the code structure is different
depending if it was async or not. Wouldn't it be nice to just write the code as
you normally would for an async function and then let the user choose which version of the
API they use? That's what gemini
is made to do! Just slap on the attribute on
your functions and go about your day.
Box<dyn Future<Output = T>>
and Pin<Box<dyn Future<Output = T>>>
async move
and async
blocksspawn
and block_on
for various executorsWhile these are unsupported they are things that should eventually be added. The code as it is now only works with a very basic understanding of how async functions are written in Rust.
In order to use gemini
you only need to import it and put the attribute on
a function you wish to have be both sync and async like so:
```rust use gemini::gemini;
pub async fn basic() -> Result<(), String> { func().await?; Ok(()) }
pub async fn func() -> Result<(), String> { Ok(()) } ```
This will then let your user choose with conditional compilation flags which version of your code they wish to use. In the case of async code it expands out to:
```rust use gemini::gemini;
pub async fn basic() -> Result<(), String> { func().await?; Ok(()) }
pub async fn func() -> Result<(), String> { Ok(()) } ```
As for the sync version it looks like:
```rust use gemini::gemini;
pub fn basic() -> Result<(), String> { func()?; Ok(()) }
pub fn func() -> Result<(), String> { Ok(()) } ```
In your Cargo.toml
add this section:
toml
[features]
default = []
sync = []
With this your users can use the default async API by listing your crate in
their Cargo.toml
file with:
toml
[dependencies]
your-crate = "<version number here>"
If they want to use the sync API then their Cargo.toml
should look like this:
toml
[dependencies]
your-crate = { version = "<version number here>", features = ["sync"] }
It's that simple. gemini
takes care of all the maintenance burden and you get
to let your api work in both contexts and giving your users more power to choose
what they want.
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.