This is a fork of the widely acclaimed async-trait crate. This crate adds two experimental attributes to async-trait that can be applied to asynchronous trait methods and associated functions to avoid heap memory allocation.
unboxed or unboxed_simple attribute is of impl Future<..> instead of Box<dyn Future<..>>.Note that, the main author of async-trait did not want to add such options, therefore this fork will not be merged into the upstream.
See async-trait for more details about async-trait.
unboxed turns an asynchronous trait method or associated function into a synchronous one returning an impl Future<..> by adding a generic associated type for the method or associated function.
```rust use asynctraitfn::{asynctrait, unboxedsimple};
pub trait SelfToUsize { #[unboxed] async fn get(&self) -> usize; }
impl SelfToUsize for u32 { #[unboxed] async fn get(&self) -> usize { *self as usize } } ```
The compiler generates the following code.
```rust pub trait SelfToUsize { fn get<'life0, 'asynctrait>(&'life0 self) -> Self::RetTypeOfGet<'life0, 'asynctrait> where 'life0: 'asynctrait, Self: 'asynctrait; type RetTypeOfGet<'life0, 'asynctrait>: ::core::future::Futuretrait where 'life0: 'asynctrait, Self: 'asynctrait, Self: 'life0; }
impl SelfToUsize for u32 {
fn get<'life0, 'asynctrait>(&'life0 self) -> Self::RetTypeOfGet<'life0, 'asynctrait>
where
'life0: 'asynctrait,
Self: 'asynctrait,
{
async move {
if let ::core::option::Option::Some(ret) = ::core::option::Option::None::
unboxed_simple is identical to unboxed except that it substitutes all the lifetime bounds and parameters with a single, fixed lifetime: 'async_trait. When code around an unboxed attribute does not compile, unboxed_simple might help.
```rust use asynctraitfn::{asynctrait, unboxedsimple};
pub trait AddOther { #[unboxed_simple] async fn add<'s, 'o>(&'a self, other: &'o usize) -> usize; }
impl AddOther for u32 { #[unboxed_simple] async fn add<'s, 'o>(&'a self, other: &'o usize) -> usize { (*self as usize) + *other } }
```
The above code expands to the following code; all the lifetime parameters are replaced with 'async_trait.
```rust pub trait AddOther { fn add<'asynctrait>( &'asynctrait self, other: &'asynctrait usize, ) -> Self::RetTypeOfAdd<'asynctrait> where Self: 'asynctrait; type RetTypeOfAdd<'asynctrait>: ::core::future::Future
impl AddOther for u32 {
fn add<'asynctrait>(
&'asynctrait self,
other: &'asynctrait usize,
) -> Self::RetTypeOfAdd<'asynctrait>
where
Self: 'asynctrait,
{
async move {
if let ::core::option::Option::Some(ret) = ::core::option::Option::None::