codspeed_divan_compat_macros/
lib.rs1mod args;
2
3use args::AttrOptions;
4use proc_macro::TokenStream;
5use proc_macro_crate::{crate_name, FoundCrate};
6use quote::{format_ident, quote, ToTokens};
7use syn::{parse_macro_input, Expr, ItemFn, Meta};
8
9#[proc_macro_attribute]
10pub fn bench_compat(attr: TokenStream, item: TokenStream) -> TokenStream {
11 let input = parse_macro_input!(item as ItemFn);
12
13 let attr_options = match AttrOptions::parse(attr) {
14 Ok(attr_options) => attr_options,
15 Err(error) => return error,
16 };
17
18 if attr_options.crate_ {
19 return quote! {
20 compile_error!("`crate` argument is yet supported with codspeed_divan_compat");
21 }
22 .into();
23 }
24
25 let codspeed_divan_crate_ident = format_ident!(
26 "{}",
27 crate_name("codspeed-divan-compat")
28 .map(|found_crate| match found_crate {
29 FoundCrate::Itself => "crate".to_string(),
30 FoundCrate::Name(name) => name,
31 })
32 .unwrap_or("codspeed_divan_compat".to_string())
33 );
34
35 let mut transfered_args = attr_options.other_args;
36
37 transfered_args.push(syn::parse_quote!(crate = ::#codspeed_divan_crate_ident));
38
39 if let Some(types) = attr_options.types {
40 transfered_args.push(Meta::NameValue(syn::MetaNameValue {
41 path: syn::parse_quote!(types),
42 eq_token: Default::default(),
43 value: Expr::Verbatim(types.into_token_stream()),
44 }));
45 }
46
47 let expanded = quote! {
49 #[::#codspeed_divan_crate_ident::bench_original(#(#transfered_args),*)]
50 #input
51 };
52
53 TokenStream::from(expanded)
54}