tracing_orchestra_macros/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3
4#[proc_macro_derive(Orchestra)]
5pub fn derive_orchestra(tokens: TokenStream) -> TokenStream {
6 let struct_ast = syn::parse_macro_input!(tokens as syn::ItemStruct);
7 let struct_attrs = struct_ast.attrs;
8 let struct_vis = struct_ast.vis;
9 let struct_name = struct_ast.ident;
10 let struct_generics = struct_ast.generics.params;
11 let struct_where = struct_ast.generics.where_clause;
12
13 let ret = quote!(
14 #(#struct_attrs)*
15 #struct_vis impl<#struct_generics> tracing_orchestra::Orchestra for #struct_name<#struct_generics> #struct_where {}
16 );
17 eprintln!("{}", ret.to_string());
18 ret.into()
19}
20
21#[proc_macro_attribute]
22pub fn orchestra(attrs: TokenStream, implementation: TokenStream) -> TokenStream {
23 let implementation_ast = syn::parse_macro_input!(implementation as syn::ItemImpl);
24 let on_attrs: proc_macro2::TokenStream = attrs.into();
25 let impl_attrs = implementation_ast.attrs;
26 let impl_defaultness = implementation_ast.defaultness;
27 let impl_unsafety = implementation_ast.unsafety;
28 let impl_generics = implementation_ast.generics.params;
29 let impl_trait = if let Some(t) = implementation_ast.trait_ {
30 if let Some(_) = t.0 {
31 let p = t.1;
32 quote!(! #p for)
33 } else {
34 let p = t.1;
35 if p.segments.is_empty() {
36 quote!()
37 } else {
38 quote!(#p for)
39 }
40 }
41 } else {
42 TokenStream::new().into()
43 };
44 let impl_type = implementation_ast.self_ty;
45 let impl_items = implementation_ast.items.into_iter().map(|item| match item {
46 syn::ImplItem::Fn(impl_fn) => {
47 let attrs = impl_fn
48 .attrs
49 .iter()
50 .filter(|attr| {
51 attr.path()
52 .segments
53 .last()
54 .map(|x| x.ident == "instrument")
55 .unwrap_or(false)
56 })
57 .collect::<Vec<_>>();
58 if attrs.is_empty() {
59 quote!(
60 #[tracing::instrument(#on_attrs)]
61 #impl_fn
62 )
63 } else {
64 let attrs_others = impl_fn
65 .attrs
66 .iter()
67 .filter(|attr2| {
68 attr2
69 .path()
70 .segments
71 .iter()
72 .last()
73 .map(|x| x.ident != "instrument")
74 .unwrap_or(false)
75 })
76 .collect::<Vec<_>>();
77 let vis = impl_fn.vis;
78 let defaultness = impl_fn.defaultness;
79 let sig = impl_fn.sig;
80 let block = impl_fn.block;
81 quote!(
82 #(#attrs)*
83 #(#attrs_others)*
84 #vis #defaultness #sig #block
85 )
86 }
87 }
88 _ => {
89 eprintln!("support only fn");
90 quote!(#item)
91 }
92 });
93 let ret = quote!(
94 #(#impl_attrs)*
95 #impl_defaultness #impl_unsafety impl #impl_generics #impl_trait #impl_type {
96 #(#impl_items)*
97 }
98 );
99
100 eprintln!("{}", ret.to_string());
101 ret.into()
102}