Skip to content

Commit 3b2c682

Browse files
committed
feat: support for trait_variant::rewrite
1 parent f1e171e commit 3b2c682

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

trait-variant/examples/variant.rs

+14
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,18 @@ where
4343
fn build<T: Display>(&self, items: impl Iterator<Item = T>) -> Self::B<T>;
4444
}
4545

46+
#[trait_variant::rewrite(Send + Sync)]
47+
pub trait GenericTraitWithBounds<'x, S: Sync, Y, const X: usize>
48+
where
49+
Y: Sync,
50+
{
51+
const CONST: usize = 3;
52+
type F;
53+
type A<const ANOTHER_CONST: u8>;
54+
type B<T: Display>: FromIterator<T>;
55+
56+
async fn take(&self, s: S);
57+
fn build<T: Display>(&self, items: impl Iterator<Item = T>) -> Self::B<T>;
58+
}
59+
4660
fn main() {}

trait-variant/src/lib.rs

+32
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,35 @@ pub fn make(
4545
) -> proc_macro::TokenStream {
4646
variant::make(attr, item)
4747
}
48+
49+
/// Creates a specialized version of a base trait that adds new bounds to `async
50+
/// fn` and/or `-> impl Trait` return types.
51+
///
52+
/// ```
53+
/// #[trait_variant::rewrite(Send)]
54+
/// trait IntFactory {
55+
/// async fn make(&self) -> i32;
56+
/// fn stream(&self) -> impl Iterator<Item = i32>;
57+
/// fn call(&self) -> u32;
58+
/// }
59+
/// ```
60+
///
61+
/// The above example causes the trait to be rewritten as:
62+
///
63+
/// ```
64+
/// # use core::future::Future;
65+
/// trait IntFactory: Send {
66+
/// fn make(&self) -> impl Future<Output = i32> + Send;
67+
/// fn stream(&self) -> impl Iterator<Item = i32> + Send;
68+
/// fn call(&self) -> u32;
69+
/// }
70+
/// ```
71+
///
72+
/// Note that ordinary methods such as `call` are not affected.
73+
#[proc_macro_attribute]
74+
pub fn rewrite(
75+
attr: proc_macro::TokenStream,
76+
item: proc_macro::TokenStream,
77+
) -> proc_macro::TokenStream {
78+
variant::rewrite(attr, item)
79+
}

trait-variant/src/variant.rs

+22
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,28 @@ pub fn make(
8181
.into()
8282
}
8383

84+
pub fn rewrite(
85+
attr: proc_macro::TokenStream,
86+
item: proc_macro::TokenStream,
87+
) -> proc_macro::TokenStream {
88+
let bounds = parse_macro_input!(attr with Punctuated::parse_separated_nonempty);
89+
let item = parse_macro_input!(item as ItemTrait);
90+
91+
let attrs = Attrs {
92+
variant: MakeVariant {
93+
name: item.ident.clone(),
94+
colon: Default::default(),
95+
bounds,
96+
},
97+
};
98+
99+
let variant = mk_variant(&attrs, &item);
100+
quote! {
101+
#variant
102+
}
103+
.into()
104+
}
105+
84106
fn mk_variant(attrs: &Attrs, tr: &ItemTrait) -> TokenStream {
85107
let MakeVariant {
86108
ref name,

0 commit comments

Comments
 (0)