async_backtrace_attributes/
lib.rs1use proc_macro2::TokenStream;
2use quote::ToTokens;
3use syn::parse::{Parse, ParseStream};
4use syn::{Attribute, Block, ItemFn, Signature, Visibility};
5
6mod expand;
7
8#[proc_macro_attribute]
9pub fn framed(
10 args: proc_macro::TokenStream,
11 item: proc_macro::TokenStream,
12) -> proc_macro::TokenStream {
13 assert!(args.is_empty());
14 instrument_precise(item.clone()).unwrap_or_else(|_err| instrument_speculative(item))
16}
17
18fn instrument_speculative(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
21 let input = syn::parse_macro_input!(item as MaybeItemFn);
22 let instrumented_function_name = input.sig.ident.to_string();
23 expand::gen_function(input.as_ref(), instrumented_function_name.as_str(), None).into()
24}
25
26fn instrument_precise(
29 item: proc_macro::TokenStream,
30) -> Result<proc_macro::TokenStream, syn::Error> {
31 let input = syn::parse::<ItemFn>(item)?;
32 let instrumented_function_name = input.sig.ident.to_string();
33
34 if let Some(async_like) = expand::AsyncInfo::from_fn(&input) {
37 return Ok(async_like.gen_async(instrumented_function_name.as_str()));
38 }
39
40 Ok(expand::gen_function((&input).into(), instrumented_function_name.as_str(), None).into())
41}
42
43#[derive(Debug, Clone)]
46struct MaybeItemFn {
47 attrs: Vec<Attribute>,
48 vis: Visibility,
49 sig: Signature,
50 block: TokenStream,
51}
52
53impl MaybeItemFn {
54 fn as_ref(&self) -> MaybeItemFnRef<'_, TokenStream> {
55 MaybeItemFnRef {
56 attrs: &self.attrs,
57 vis: &self.vis,
58 sig: &self.sig,
59 block: &self.block,
60 }
61 }
62}
63
64impl Parse for MaybeItemFn {
67 fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
68 let attrs = input.call(syn::Attribute::parse_outer)?;
69 let vis: Visibility = input.parse()?;
70 let sig: Signature = input.parse()?;
71 let block: TokenStream = input.parse()?;
72 Ok(Self {
73 attrs,
74 vis,
75 sig,
76 block,
77 })
78 }
79}
80
81#[derive(Debug, Clone)]
85struct MaybeItemFnRef<'a, B: ToTokens> {
86 attrs: &'a Vec<Attribute>,
87 vis: &'a Visibility,
88 sig: &'a Signature,
89 block: &'a B,
90}
91
92impl<'a> From<&'a ItemFn> for MaybeItemFnRef<'a, Box<Block>> {
93 fn from(val: &'a ItemFn) -> Self {
94 MaybeItemFnRef {
95 attrs: &val.attrs,
96 vis: &val.vis,
97 sig: &val.sig,
98 block: &val.block,
99 }
100 }
101}