better but still not workable
This commit is contained in:
12
teleprof-macros/Cargo.toml
Normal file
12
teleprof-macros/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "teleprof-macros"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "2.0", features = ["full"] }
|
||||
quote = "1.0"
|
||||
proc-macro2 = "1.0"
|
||||
58
teleprof-macros/src/lib.rs
Normal file
58
teleprof-macros/src/lib.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, ItemFn, Lit};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn instrument(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let input_fn = parse_macro_input!(input as ItemFn);
|
||||
|
||||
// Parse custom name from attributes
|
||||
let mut custom_name: Option<String> = None;
|
||||
|
||||
let args_parser = syn::meta::parser(|meta| {
|
||||
if meta.path.is_ident("name") {
|
||||
let value: Lit = meta.value()?.parse()?;
|
||||
if let Lit::Str(lit_str) = value {
|
||||
custom_name = Some(lit_str.value());
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Err(meta.error("unsupported attribute"))
|
||||
}
|
||||
});
|
||||
|
||||
let _ = parse_macro_input!(args with args_parser);
|
||||
|
||||
let fn_name = &input_fn.sig.ident;
|
||||
let span_name = custom_name.unwrap_or_else(|| fn_name.to_string());
|
||||
|
||||
let fn_vis = &input_fn.vis;
|
||||
let fn_sig = &input_fn.sig;
|
||||
let fn_block = &input_fn.block;
|
||||
let fn_attrs = &input_fn.attrs;
|
||||
|
||||
// Check if function is async
|
||||
let is_async = fn_sig.asyncness.is_some();
|
||||
|
||||
let instrumented = if is_async {
|
||||
// For async functions, we need to instrument the future
|
||||
quote! {
|
||||
#(#fn_attrs)*
|
||||
#fn_vis #fn_sig {
|
||||
let _guard = ::teleprof::SpanGuard::new(#span_name);
|
||||
async move #fn_block
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// For sync functions, straightforward instrumentation
|
||||
quote! {
|
||||
#(#fn_attrs)*
|
||||
#fn_vis #fn_sig {
|
||||
let _guard = ::teleprof::SpanGuard::new(#span_name);
|
||||
#fn_block
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(instrumented)
|
||||
}
|
||||
Reference in New Issue
Block a user