trait_variant/
lib.rs

1// Copyright (c) 2023 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9#![doc = include_str!("../README.md")]
10
11mod variant;
12
13/// Creates a specialized version of a base trait that adds bounds to `async
14/// fn` and/or `-> impl Trait` return types.
15///
16/// ```
17/// #[trait_variant::make(Send)]
18/// trait IntFactory {
19///     async fn make(&self) -> i32;
20///     fn stream(&self) -> impl Iterator<Item = i32>;
21///     fn call(&self) -> u32;
22/// }
23/// ```
24///
25/// The above example causes the trait to be rewritten as:
26///
27/// ```
28/// # use core::future::Future;
29/// trait IntFactory: Send {
30///     fn make(&self) -> impl Future<Output = i32> + Send;
31///     fn stream(&self) -> impl Iterator<Item = i32> + Send;
32///     fn call(&self) -> u32;
33/// }
34/// ```
35///
36/// Note that ordinary methods such as `call` are not affected.
37///
38/// If you want to preserve an original trait untouched, `make` can be used to create a new trait with bounds on `async
39/// fn` and/or `-> impl Trait` return types.
40///
41/// ```
42/// #[trait_variant::make(IntFactory: Send)]
43/// trait LocalIntFactory {
44///     async fn make(&self) -> i32;
45///     fn stream(&self) -> impl Iterator<Item = i32>;
46///     fn call(&self) -> u32;
47/// }
48/// ```
49///
50/// The example causes a second trait called `IntFactory` to be created.
51/// Implementers of the trait can choose to implement the variant instead of the
52/// original trait. The macro creates a blanket impl which ensures that any type
53/// which implements the variant also implements the original trait.
54#[proc_macro_attribute]
55pub fn make(
56    attr: proc_macro::TokenStream,
57    item: proc_macro::TokenStream,
58) -> proc_macro::TokenStream {
59    variant::make(attr, item)
60}