api_response_macros/
lib.rs

1use proc_macro::TokenStream;
2use proc_macro2::{Literal, Span};
3use quote::quote;
4use syn::Ident;
5mod enum_digits;
6use syn::{DeriveInput, parse_macro_input};
7
8#[proc_macro_derive(ErrTypeConstructor)]
9pub fn err_type_constructor(_input: TokenStream) -> TokenStream {
10    let mut new_type_methods = Vec::new();
11
12    for i in 1000..=4293u16 {
13        let flag_value = Literal::u16_unsuffixed(i);
14        let new_type_method_ident = Ident::new(&format!("T{i:04}"), Span::call_site());
15
16        new_type_methods.push(quote! {
17            #[allow(non_snake_case)]
18            #[inline]
19            pub const fn #new_type_method_ident(text: &'static str) -> ErrType {
20                ErrType { text, flag: #flag_value }
21            }
22        });
23    }
24
25    let expanded = quote! {
26        impl ErrType {
27            #(#new_type_methods)*
28        }
29    };
30
31    TokenStream::from(expanded)
32}
33
34#[proc_macro_derive(ErrPathConstructor)]
35pub fn err_path_constructor(input: TokenStream) -> TokenStream {
36    let ast = parse_macro_input!(input as DeriveInput);
37    let expanded = match ast.ident.to_string().as_str() {
38        "ErrPathRoot" => {
39            let mut new_root_methods = Vec::new();
40            let mut new_parent_methods = Vec::new();
41
42            for i in 0..=99u8 {
43                let flag_value = Literal::u8_unsuffixed(i);
44                let new_root_method_ident = Ident::new(&format!("X{i:02}"), Span::call_site());
45                let new_parent_method_ident = Ident::new(&format!("Y{i:02}"), Span::call_site());
46
47                new_root_methods.push(quote! {
48                    #[allow(non_snake_case)]
49                    #[inline]
50                    pub const fn #new_root_method_ident(name: &'static str) -> ErrPathRoot {
51                        ErrPathRoot { name, flag: #flag_value }
52                    }
53                });
54                new_parent_methods.push(quote! {
55                    #[allow(non_snake_case)]
56                    #[inline]
57                    pub const fn #new_parent_method_ident(self, name: &'static str) -> ErrPathParent {
58                        ErrPathParent { root: self, name, flag: #flag_value }
59                    }
60                });
61            }
62
63            quote! {
64                impl ErrPathRoot {
65                    #(#new_root_methods)*
66
67                    #(#new_parent_methods)*
68                }
69            }
70        }
71
72        "ErrPathParent" => {
73            let mut new_path_methods = Vec::new();
74
75            for i in 0..=99u8 {
76                let flag_value = Literal::u8_unsuffixed(i);
77                let new_path_method_ident = Ident::new(&format!("Z{i:02}"), Span::call_site());
78
79                new_path_methods.push(quote! {
80                    #[allow(non_snake_case)]
81                    #[inline]
82                    pub const fn #new_path_method_ident(self, name: &'static str) -> ErrPath {
83                        ErrPath { parent: self, name, flag: #flag_value }
84                    }
85                });
86            }
87
88            quote! {
89                impl ErrPathParent {
90                    #(#new_path_methods)*
91                }
92            }
93        }
94
95        _ => {
96            quote! {}
97        }
98    };
99
100    TokenStream::from(expanded)
101}
102
103#[proc_macro]
104pub fn enum_digits(input: TokenStream) -> TokenStream {
105    enum_digits::enum_digits(input)
106}