cgp_async_macro/
lib.rs

1#![no_std]
2
3/*!
4   This library provides helper macros for using async functions in traits.
5*/
6
7extern crate alloc;
8extern crate proc_macro;
9
10use proc_macro::TokenStream;
11
12mod impl_async;
13mod strip_async;
14
15/**
16   This macro can be used in place of the [`macro@native_async`] macro
17   to strip away all use of `async` and `.await` syntax. This helps emulate
18   async-generic by turnining async functions into sync functions.
19*/
20#[proc_macro_attribute]
21pub fn strip_async(_attr: TokenStream, stream: TokenStream) -> TokenStream {
22    strip_async::strip_async(stream.into()).into()
23}
24
25/**
26    The `#[async_trait]` macro is used to desugar async functions in traits
27    to return `impl Future + Send`.
28
29    This macro is required mainly to get around the current limitation of
30    [async functions in traits](https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits/),
31    which would produce a lint warning for `async_fn_in_trait` if bare async
32    functions are defined in a trait.
33
34    The default approach adopted by CGP is to always include a `Send` bound
35    on the desugared `Future`, so that any async function that indirectly calls
36    the method can still implement `Send` be be used with libraries such as `tokio::spawn`.
37
38    It is possible to remove default `Send` by deactivating the `send` feature in the `cgp-async`
39    crate. However, the removal may be unreliable, as the feature flag could still be accidentally
40    enabled by one of the dependencies.
41
42    Note that although the macro shares the same name as the
43    [`async-trait`](https://docs.rs/async-trait) crate, it is implemented very differently.
44    The other crate with the same name returns a `Pin<Box<dyn Future + Send>>`, while
45    this macro returns a `impl Future + Send`.
46
47    ## Example
48
49    Given the following trait definition:
50
51    ```rust,ignore
52    #[async_trait]
53    pub trait CanRun {
54        async fn run(&self);
55    }
56    ```
57
58    The macro would desugar it to the following:
59
60    ```rust,ignore
61    pub trait CanRun {
62        fn run(&self) -> impl Future<Output = ()> + Send;
63    }
64    ```
65*/
66#[proc_macro_attribute]
67pub fn native_async(_attr: TokenStream, stream: TokenStream) -> TokenStream {
68    impl_async::impl_async(stream.into()).into()
69}