zolt_proc/
lib.rs

1use proc_macro::TokenStream;
2
3#[proc_macro]
4pub fn msg_macros(tokens: TokenStream) -> TokenStream {
5    let items: Vec<String> = tokens.into_iter().map(|item| item.to_string()).collect();
6    let macro_name = items.get(0).expect("No macro name was supplied");
7    let msg_type = items
8        .get(2)
9        .expect("No message type was specified")
10        .trim_start_matches('"')
11        .trim_end_matches('"');
12    let msg_prefix = items.get(4).expect("No message prefix was specified");
13    let msg_color = items.get(6).expect("No message color was specified");
14    let target_macro = items
15        .get(8)
16        .expect("No target printing macro was specified");
17
18    let gen_macro = |name, fmt_macro, action, suffix, fmt_note| {
19        format!(
20            r#"
21            /// {action} a message suitable for {msg_type} information{suffix}.
22            /// It takes the same arguments as [`{fmt_macro}!`].{}
23            #[macro_export]
24            macro_rules! {name} {{
25                ($($arg:tt)*) => {{{{
26                    let prefix = {{
27                        use $crate::colored::Colorize;
28                        {msg_prefix}.{msg_color}().bold()
29                    }};
30                    {fmt_macro}!("{{}}: {{}}", prefix, format!($($arg)*))
31                }}}}
32            }}
33        "#,
34            if fmt_note {
35                format!(
36                "\n///\n/// It outputs to [`std::io::{}`] by default. If you need more control than that, use [`{macro_name}fmt!`] instead.",
37                if target_macro == "print" {
38                    "Stdout"
39                } else {
40                    "Stderr"
41                }
42            )
43            } else {
44                "".to_owned()
45            }
46        )
47    };
48    let mut macros = gen_macro(format!("{macro_name}fmt"), "format", "Format", "", false);
49    macros += &gen_macro(macro_name.to_owned(), target_macro, "Print", "", true);
50    macros += &gen_macro(
51        format!("{macro_name}ln"),
52        &format!("{target_macro}ln"),
53        "Print",
54        ", with a newline at the end",
55        true,
56    );
57    // panic!("{macros}");
58    macros.parse().unwrap()
59}