arcs_logging_rs_proc_macro/
lib.rs1use std::str::FromStr;
2
3use proc_macro::TokenStream;
4use quote::{quote, __private::TokenStream as QuoteTokenStream};
5use syn::Ident;
6
7
8fn parse_into_ident(ident: &str) -> Result<Ident, QuoteTokenStream> {
9 syn::parse::<Ident>(
10 TokenStream
11 ::from_str(ident)
12 .map_err(|error| ToString::to_string(&error))
13 .map_err(|error| quote!{
14 compile_error!(#error);
15 })?,
16 ).map_err(
17 |err| err.to_compile_error(),
18 )
19}
20
21fn parse_into_idents(idents: (&str, &str, &str)) -> Result<(Ident, Ident, Ident), QuoteTokenStream> {
22 match (parse_into_ident(idents.0), parse_into_ident(idents.1), parse_into_ident(idents.2)) {
23 (Ok(ident_1), Ok(ident_2), Ok(ident_3)) => Ok((ident_1, ident_2, ident_3)),
24 (Err(e_1), Err(e_2), Err(e_3)) => Err(quote!{ #e_1 #e_2 #e_3 }),
25 (Err(e_1), Err(e_2), Ok(_)) => Err(quote!{ #e_1 #e_2 }),
26 (Err(e_1), Ok(_), Err(e_3)) => Err(quote!{ #e_1 #e_3 }),
27 (Err(e_1), Ok(_), Ok(_)) => Err(quote!{ #e_1 }),
28 (Ok(_), Err(e_2), Err(e_3)) => Err(quote!{ #e_2 #e_3 }),
29 (Ok(_), Err(e_2), Ok(_)) => Err(quote!{ #e_2 }),
30 (Ok(_), Ok(_), Err(e_3)) => Err(quote!{ #e_3 }),
31 }
32}
33
34#[proc_macro]
35pub fn with_target(input: TokenStream) -> TokenStream {
36 let lit: Result<syn::LitStr, _> = syn::parse(input);
37
38 match lit {
39 Ok(lit) => {
40 let macros = [
41 ("error", "error", "log_error"),
42 ("warn", "warn", "log_warn"),
43 ("info", "info", "log_info"),
44 ("debug", "debug", "log_debug"),
45 ("trace", "trace", "log_trace"),
46 ];
47 let inner_stream: QuoteTokenStream = macros
48 .into_iter()
49 .map(parse_into_idents)
50 .map(|name| match name {
51 Ok(idents) => {
52 let (orig_macro_name, export_name, this_macro_name) = idents;
53 quote! {
54 #[macro_export]
55 macro_rules! #this_macro_name {
56 (target: $target:expr, $($arg:tt)+) => {
57 arcs_logging_rs::__internal_redirects::#orig_macro_name!(target: $target, $($arg)+)
58 };
59 ($($arg:tt)+) => {
60 arcs_logging_rs::__internal_redirects::#orig_macro_name!(target: #lit, $($arg)+)
61 };
62 }
63 pub use #this_macro_name as #export_name;
64 }
65 },
66 Err(err) => err
67 })
68 .collect();
69
70
71 let macro_names = [
72 "error",
73 "warn",
74 "info",
75 "debug",
76 "trace",
77 ];
78 let use_stream: QuoteTokenStream = macro_names
79 .into_iter()
80 .map(parse_into_ident)
81 .map(|result| match result {
82 Ok(ident) => quote!{ #ident, },
83 Err(err) => err
84 })
85 .collect();
86
87 quote!{
88 #[doc(hidden)]
89 mod __internal_logging_macros {
90 #inner_stream
91 }
92
93 pub use __internal_logging_macros::{#use_stream};
94
95 pub static DEFAULT_TARGET_NAME: &str = #lit;
96
97 }.into()
98 },
99 Err(err) => {
100 let compile_error_tokens = err.to_compile_error();
101 quote!{
102 #compile_error_tokens
103 }
104 }.into()
105 }
106}