api-response-macros 0.16.3

Macros for api-response crate
Documentation
use proc_macro::TokenStream;
use proc_macro2::{Literal, Span};
use quote::quote;
use syn::Ident;
mod enum_digits;
use syn::{DeriveInput, parse_macro_input};

#[proc_macro_derive(ErrTypeConstructor)]
pub fn err_type_constructor(_input: TokenStream) -> TokenStream {
    let mut new_type_methods = Vec::new();

    for i in 1000..=4293u16 {
        let flag_value = Literal::u16_unsuffixed(i);
        let new_type_method_ident = Ident::new(&format!("T{i:04}"), Span::call_site());

        new_type_methods.push(quote! {
            #[allow(non_snake_case)]
            #[inline]
            pub const fn #new_type_method_ident(text: &'static str) -> ErrType {
                ErrType { text, flag: #flag_value }
            }
        });
    }

    let expanded = quote! {
        impl ErrType {
            #(#new_type_methods)*
        }
    };

    TokenStream::from(expanded)
}

#[proc_macro_derive(ErrPathConstructor)]
pub fn err_path_constructor(input: TokenStream) -> TokenStream {
    let ast = parse_macro_input!(input as DeriveInput);
    let expanded = match ast.ident.to_string().as_str() {
        "ErrPathRoot" => {
            let mut new_root_methods = Vec::new();
            let mut new_parent_methods = Vec::new();

            for i in 0..=99u8 {
                let flag_value = Literal::u8_unsuffixed(i);
                let new_root_method_ident = Ident::new(&format!("X{i:02}"), Span::call_site());
                let new_parent_method_ident = Ident::new(&format!("Y{i:02}"), Span::call_site());

                new_root_methods.push(quote! {
                    #[allow(non_snake_case)]
                    #[inline]
                    pub const fn #new_root_method_ident(name: &'static str) -> ErrPathRoot {
                        ErrPathRoot { name, flag: #flag_value }
                    }
                });
                new_parent_methods.push(quote! {
                    #[allow(non_snake_case)]
                    #[inline]
                    pub const fn #new_parent_method_ident(self, name: &'static str) -> ErrPathParent {
                        ErrPathParent { root: self, name, flag: #flag_value }
                    }
                });
            }

            quote! {
                impl ErrPathRoot {
                    #(#new_root_methods)*

                    #(#new_parent_methods)*
                }
            }
        }

        "ErrPathParent" => {
            let mut new_path_methods = Vec::new();

            for i in 0..=99u8 {
                let flag_value = Literal::u8_unsuffixed(i);
                let new_path_method_ident = Ident::new(&format!("Z{i:02}"), Span::call_site());

                new_path_methods.push(quote! {
                    #[allow(non_snake_case)]
                    #[inline]
                    pub const fn #new_path_method_ident(self, name: &'static str) -> ErrPath {
                        ErrPath { parent: self, name, flag: #flag_value }
                    }
                });
            }

            quote! {
                impl ErrPathParent {
                    #(#new_path_methods)*
                }
            }
        }

        _ => {
            quote! {}
        }
    };

    TokenStream::from(expanded)
}

#[proc_macro]
pub fn enum_digits(input: TokenStream) -> TokenStream {
    enum_digits::enum_digits(input)
}