Skip to content

Commit

Permalink
feat: support for trait_variant::rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
sargarass committed Feb 4, 2024
1 parent f1e171e commit a50cd80
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
14 changes: 14 additions & 0 deletions trait-variant/examples/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,18 @@ where
fn build<T: Display>(&self, items: impl Iterator<Item = T>) -> Self::B<T>;
}

#[trait_variant::rewrite(Send + Sync)]
pub trait GenericTraitWithBounds<'x, S: Sync, Y, const X: usize>
where
Y: Sync,
{
const CONST: usize = 3;
type F;
type A<const ANOTHER_CONST: u8>;
type B<T: Display>: FromIterator<T>;

async fn take(&self, s: S);
fn build<T: Display>(&self, items: impl Iterator<Item = T>) -> Self::B<T>;
}

fn main() {}
32 changes: 32 additions & 0 deletions trait-variant/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,35 @@ pub fn make(
) -> proc_macro::TokenStream {
variant::make(attr, item)
}

/// Creates a specialized version of a base trait that adds new bounds to `async
/// fn` and/or `-> impl Trait` return types.
///
/// ```
/// #[trait_variant::rewrite(Send)]
/// trait IntFactory {
/// async fn make(&self) -> i32;
/// fn stream(&self) -> impl Iterator<Item = i32>;
/// fn call(&self) -> u32;
/// }
/// ```
///
/// The above example causes the trait to be rewritten as:
///
/// ```
/// # use core::future::Future;
/// trait IntFactory: Send {
/// fn make(&self) -> impl Future<Output = i32> + Send;
/// fn stream(&self) -> impl Iterator<Item = i32> + Send;
/// fn call(&self) -> u32;
/// }
/// ```
///
/// Note that ordinary methods such as `call` are not affected.
#[proc_macro_attribute]
pub fn rewrite(
attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
variant::rewrite(attr, item)
}
24 changes: 23 additions & 1 deletion trait-variant/src/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

use std::iter;

use proc_macro2::TokenStream;
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{
parse::{Parse, ParseStream},
Expand Down Expand Up @@ -81,6 +81,28 @@ pub fn make(
.into()
}

pub fn rewrite(
attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let bounds = parse_macro_input!(attr with Punctuated::parse_separated_nonempty);
let item = parse_macro_input!(item as ItemTrait);

let attrs = Attrs {
variant: MakeVariant {
name: item.ident.clone(),
colon: Default::default(),
bounds,
},
};

let variant = mk_variant(&attrs, &item);
quote! {
#variant
}
.into()
}

fn mk_variant(attrs: &Attrs, tr: &ItemTrait) -> TokenStream {
let MakeVariant {
ref name,
Expand Down

0 comments on commit a50cd80

Please sign in to comment.