Skip to content

Instantly share code, notes, and snippets.

@freedomtowin
Created June 28, 2025 21:17
Show Gist options
  • Select an option

  • Save freedomtowin/cd98909357946c448982c9b4110cbf62 to your computer and use it in GitHub Desktop.

Select an option

Save freedomtowin/cd98909357946c448982c9b4110cbf62 to your computer and use it in GitHub Desktop.
Example of creating a Gist using Python
#[proc_macro_attribute]
pub fn log_entry_and_exit(attr: TokenStream, item: TokenStream) -> TokenStream {
// Attribute flags
let mut log_time = false;
let mut log_ret = false;
// Create parser
let arg_parser = syn::meta::parser(|meta| {
if meta.path.is_ident("time") {
log_time = true;
Ok(())
} else if meta.path.is_ident("ret") {
log_ret = true;
Ok(())
} else {
// propagate errors
Err(meta.error("expected `time` or `ret`"))
}
});
let _ = parse_macro_input!(attr with arg_parser);
// Parse the annotated function
let input_fn: ItemFn = parse_macro_input!(item as ItemFn);
let vis = &input_fn.vis;
let sig = &input_fn.sig;
let body = &input_fn.block;
let ident = &input_fn.sig.ident;
// Build snippets that depend on flags
let timer_start = if log_time {
quote! { let __start = std::time::Instant::now(); }
} else {
quote! {}
};
let timer_end = if log_time {
quote! {
let __elapsed = __start.elapsed();
println!("Exiting {} (elapsed: {:?})",
stringify!(#ident), __elapsed);
}
} else {
quote! { println!("Exiting {}", stringify!(#ident)); }
};
let print_ret = if log_ret {
quote! {
println!("Return value from {}: {:?}", stringify!(#ident), &__ret);
}
} else {
quote! {}
};
// Splice everything together
quote! {
#vis #sig {
println!("Entering {}", stringify!(#ident));
#timer_start
// Execute the user’s body, capture the return value.
let __ret = (|| #body)();
#print_ret
#timer_end
__ret
}
}.into()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment