mobench_macros/lib.rs
1//! Procedural macros for bench-sdk
2//!
3//! This crate provides the `#[benchmark]` attribute macro for marking functions
4//! as benchmarkable. Functions marked with this attribute are automatically
5//! registered and can be discovered at runtime.
6
7use proc_macro::TokenStream;
8use quote::quote;
9use syn::{ItemFn, parse_macro_input};
10
11/// Marks a function as a benchmark.
12///
13/// This macro registers the function in the global benchmark registry and
14/// makes it available for execution via the bench-sdk runtime.
15///
16/// # Example
17///
18/// ```ignore
19/// use mobench_sdk::benchmark;
20///
21/// #[benchmark]
22/// fn fibonacci_bench() {
23/// let result = fibonacci(30);
24/// std::hint::black_box(result);
25/// }
26/// ```
27///
28/// The macro preserves the original function and creates a registration entry
29/// that allows the benchmark to be discovered and invoked by name.
30#[proc_macro_attribute]
31pub fn benchmark(_attr: TokenStream, item: TokenStream) -> TokenStream {
32 let input_fn = parse_macro_input!(item as ItemFn);
33
34 let fn_name = &input_fn.sig.ident;
35 let fn_name_str = fn_name.to_string();
36 let vis = &input_fn.vis;
37 let sig = &input_fn.sig;
38 let block = &input_fn.block;
39 let attrs = &input_fn.attrs;
40
41 // Get the module path for fully-qualified name
42 // Note: This will generate the fully-qualified name at compile time
43 let module_path = quote! { module_path!() };
44
45 let expanded = quote! {
46 // Preserve the original function
47 #(#attrs)*
48 #vis #sig {
49 #block
50 }
51
52 // Register the function with inventory
53 ::inventory::submit! {
54 ::mobench_sdk::registry::BenchFunction {
55 name: ::std::concat!(#module_path, "::", #fn_name_str),
56 invoke: |_args| {
57 #fn_name();
58 Ok(())
59 },
60 }
61 }
62 };
63
64 TokenStream::from(expanded)
65}