async_trait_fn/lib.rs
1//! [![github]](https://github.com/wvwwvwwv/async-trait-fn) [![crates-io]](https://crates.io/crates/async-trait-fn) [![docs-rs]](https://docs.rs/async-trait-fn)
2//!
3//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6//!
7//! # async-trait-fn
8//!
9//! This is a fork of the widely acclaimed [async-trait](https://github.com/dtolnay/async-trait)
10//! crate. This crate adds two experimental attributes to
11//! [async-trait](https://github.com/dtolnay/async-trait) that can be applied to asynchronous trait
12//! methods and associated functions to avoid heap memory allocation.
13//!
14//! ### `unboxed`
15//!
16//! An `async fn` without a default implementation may get transformed into a
17//! method that returns `impl Future + Send + 'async_trait` when
18//! `#[macro@unboxed]` is marked on both the trait and the impl blocks.
19//! `#[macro@unboxed]` requires the following unstable language features:
20//! `associated_type_bounds` and `type_alias_impl_trait`.
21//!
22//! ```ignore
23//! #![feature(associated_type_bounds, type_alias_impl_trait)]
24//! # use async_trait_fn::async_trait;
25//!
26//! #[async_trait]
27//! pub trait MyFastTrait {
28//! /// `cnt_fast` returns an instance of a concrete `Future` type.
29//! #[unboxed]
30//! async fn cnt_fast(&self) -> usize;
31//!
32//! // presumably other methods
33//! }
34//!
35//! struct MyType(usize);
36//!
37//! #[async_trait]
38//! impl MyFastTrait for MyType {
39//! #[unboxed]
40//! async fn cnt_fast(&self) -> usize {
41//! self.0
42//! }
43//! }
44//!
45//! let value = MyType(1);
46//! let unboxed_future = value.cnt_fast();
47//! ```
48//!
49//! The feature is not generally applicable due to a
50//! [bug](https://github.com/rust-lang/rust/issues/95719) in the Rust type
51//! system.
52//!
53//! ### `unboxed_simple`
54//!
55//! `unboxed_simple` is identical to `unboxed` except that all the lifetime
56//! bounds in the type and parameters are substituted with a single lifetime.
57
58#![doc(html_root_url = "https://docs.rs/async-trait/0.1.77")]
59#![allow(
60 clippy::default_trait_access,
61 clippy::doc_markdown,
62 clippy::explicit_auto_deref,
63 clippy::if_not_else,
64 clippy::items_after_statements,
65 clippy::match_like_matches_macro,
66 clippy::module_name_repetitions,
67 clippy::shadow_unrelated,
68 clippy::similar_names,
69 clippy::too_many_lines
70)]
71
72extern crate proc_macro;
73
74mod args;
75mod bound;
76mod expand;
77mod lifetime;
78mod parse;
79mod receiver;
80mod verbatim;
81
82use crate::args::Args;
83use crate::expand::expand;
84use crate::parse::Item;
85use proc_macro::TokenStream;
86use quote::quote;
87use syn::parse_macro_input;
88
89#[proc_macro_attribute]
90pub fn async_trait(args: TokenStream, input: TokenStream) -> TokenStream {
91 let args = parse_macro_input!(args as Args);
92 let mut item = parse_macro_input!(input as Item);
93 expand(&mut item, args.local);
94 TokenStream::from(quote!(#item))
95}
96
97#[proc_macro_attribute]
98pub fn unboxed(_args: TokenStream, input: TokenStream) -> TokenStream {
99 input
100}
101
102#[proc_macro_attribute]
103pub fn unboxed_simple(_args: TokenStream, input: TokenStream) -> TokenStream {
104 input
105}