1#![feature(
5 proc_macro_def_site,
6 extend_one,
7 decl_macro,
8 macro_derive,
9 if_let_guard,
10 yeet_expr,
11 try_find,
12 try_blocks,
13 super_let,
14 exact_size_is_empty
15)]
16
17#![expect(clippy::needless_continue, reason = "Macro-generated code")]
19
20mod format;
22mod formattable;
23mod parse;
24mod parse_error;
25mod parse_recursive;
26mod print;
27mod util;
28
29use {app_error::{AppError, app_error}, core::panic::UnwindSafe};
31
32#[proc_macro_derive(ParseError, attributes(error, parse_error))]
33pub fn derive_parse_error(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
34 self::try_derive(input, parse_error::derive)
35}
36
37#[proc_macro_derive(Parse, attributes(parse))]
38pub fn derive_parser(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
39 self::try_derive(input, parse::derive)
40}
41
42#[proc_macro_derive(ParseRecursive, attributes(parse_recursive))]
43pub fn derive_parser_recursive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
44 self::try_derive(input, parse_recursive::derive)
45}
46
47#[proc_macro_derive(Formattable, attributes(formattable))]
48pub fn derive_formattable(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
49 self::try_derive(input, formattable::derive)
50}
51
52#[proc_macro_derive(Format, attributes(format))]
53pub fn derive_format(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
54 self::try_derive(input, format::derive)
55}
56
57#[proc_macro_derive(Print, attributes())]
58pub fn derive_print(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
59 self::try_derive(input, print::derive)
60}
61
62fn try_derive(
63 input: proc_macro::TokenStream,
64 f: impl FnOnce(proc_macro::TokenStream) -> Result<proc_macro::TokenStream, AppError> + UnwindSafe,
65) -> proc_macro::TokenStream {
66 std::panic::catch_unwind(move || f(input)).map_err(
67 |payload| app_error!("Derive macro panicked: {payload:?}")
68 ).flatten().unwrap_or_else(|err| {
69 let err = err.to_string();
70 quote::quote! {
71 compile_error! { #err }
72 }.into()
73 })
74}