Skip to main content

err_trail_macros/
lib.rs

1extern crate proc_macro;
2use proc_macro::TokenStream;
3use quote::quote;
4
5fn generate_logger_impl(level: &str, args: TokenStream) -> TokenStream {
6    let args_tokens = proc_macro2::TokenStream::from(args);
7    let level_ident = syn::Ident::new(level, proc_macro2::Span::call_site());
8
9    let mut statements: Vec<proc_macro2::TokenStream> = Vec::new();
10
11    #[cfg(feature = "tracing")]
12    statements.push(quote! {
13        tracing::#level_ident!("{}", args);
14    });
15    #[cfg(feature = "log")]
16    statements.push(quote! {
17        log::#level_ident!("{}", args);
18    });
19    #[cfg(feature = "defmt")]
20    statements.push(quote! {
21        defmt::#level_ident!("{}", defmt::Display2Format(&args));
22    });
23
24    #[cfg(any(feature = "tracing", feature = "log", feature = "defmt"))]
25    let expanded = quote! {{
26        #[allow(unused_variables)]
27        let args = format_args!(#args_tokens);
28        #(#statements)*
29    }};
30    #[cfg(not(any(feature = "tracing", feature = "log", feature = "defmt")))]
31    let expanded = quote! {};
32
33    TokenStream::from(expanded)
34}
35
36#[proc_macro]
37pub fn error(input: TokenStream) -> TokenStream {
38    generate_logger_impl("error", input)
39}
40
41#[proc_macro]
42pub fn warn(input: TokenStream) -> TokenStream {
43    generate_logger_impl("warn", input)
44}
45
46#[proc_macro]
47pub fn info(input: TokenStream) -> TokenStream {
48    generate_logger_impl("info", input)
49}
50
51#[proc_macro]
52pub fn debug(input: TokenStream) -> TokenStream {
53    generate_logger_impl("debug", input)
54}
55
56#[proc_macro]
57pub fn trace(input: TokenStream) -> TokenStream {
58    generate_logger_impl("trace", input)
59}