Skip to main content

rustidy_macros/
lib.rs

1//! Macros for [`rustidy`](../rustidy/index.html)
2
3// Features
4#![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// Lints
18#![expect(clippy::needless_continue, reason = "Macro-generated code")]
19
20// Modules
21mod format;
22mod formattable;
23mod parse;
24mod parse_error;
25mod parse_recursive;
26mod print;
27mod util;
28
29// Imports
30use {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}