axum_error_handler/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{Attribute, DeriveInput, Fields, LitStr, parse::ParseStream, parse_macro_input};
4
5pub(crate) mod response;
6
7#[proc_macro_derive(AxumErrorResponse, attributes(status_code, code, response))]
8pub fn derive_axum_error_response(input: TokenStream) -> TokenStream {
9    // Parse the input tokens into a syntax tree
10    let input = parse_macro_input!(input as DeriveInput);
11    let name = input.ident;
12
13    let variants = if let syn::Data::Enum(data_enum) = input.data {
14        data_enum.variants
15    } else {
16        panic!("AxumErrorResponse can only be derived for enums");
17    };
18
19    let match_arms = variants
20        .iter()
21        .map(|variant| response::parse_response(&name, variant));
22
23    // Generate the final impl block
24    let expanded = quote! {
25        impl axum::response::IntoResponse for #name {
26            fn into_response(self) -> axum::response::Response {
27                match self {
28                    #(#match_arms),*
29                }
30            }
31        }
32    };
33
34    TokenStream::from(expanded)
35}