Created
June 28, 2025 21:17
-
-
Save freedomtowin/cd98909357946c448982c9b4110cbf62 to your computer and use it in GitHub Desktop.
Example of creating a Gist using Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #[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