rsmack-seanum 0.18.0

Enhanced documentation macro with constant evaluation
Documentation
use darling::FromMeta;
use proc_macro2::TokenStream;
use quote::quote;
use rsmack_utils::megamac::ExecEnv;
use syn::*;

#[derive(Debug, FromMeta)]
pub struct Args {
    /// The Rust type for the enum in the database
    rs_type: syn::Ident,
    /// The database type for the enum
    db_type: syn::LitStr,
}

/// Execute seanum macro
pub fn exec(args: Args, item: ItemEnum, _env: ExecEnv) -> TokenStream {
    let enum_name = &item.ident;
    let enum_name_str = enum_name.to_string();

    // Convert enum name to snake_case for database name
    let db_enum_name = enum_name_str
        .chars()
        .enumerate()
        .map(|(i, c)| {
            if i > 0 && c.is_uppercase() {
                format!("_{}", c.to_lowercase().next().unwrap())
            } else {
                c.to_lowercase().next().unwrap().to_string()
            }
        })
        .collect::<String>();

    // Collect existing attributes (excluding the seanum attribute)
    let existing_attrs: Vec<_> = item
        .attrs
        .iter()
        .filter(|attr| {
            // Keep attributes that are not the seanum attribute
            !attr.path().is_ident("seanum")
        })
        .collect();

    // Generate the string values for each variant
    let variants_with_attrs: Vec<_> = item
        .variants
        .iter()
        .map(|variant| {
            let variant_name = &variant.ident;
            let variant_name_str = variant_name.to_string();

            // Collect existing variant attributes
            let existing_variant_attrs = &variant.attrs;

            // Create the sea_orm attribute for this variant
            let sea_orm_attr = quote! {
                #[sea_orm(string_value = #variant_name_str)]
            };

            quote! {
                #(#existing_variant_attrs)*
                #sea_orm_attr
                #variant_name
            }
        })
        .collect();

    // Generate the final enum
    let visibility = &item.vis;
    let generics = &item.generics;
    let rs_type = args.rs_type.to_string();
    let db_type = args.db_type;

    let result = quote! {



        #(#existing_attrs)*
        #[derive(
            Clone, ::fake::Dummy, Debug, PartialEq, ::sea_orm::EnumIter, ::sea_orm::DeriveActiveEnum, Eq, ::serde::Serialize, ::serde::Deserialize, Hash
        )]
        #[sea_orm(rs_type = #rs_type, db_type = #db_type, enum_name = #db_enum_name)]
        #visibility enum #enum_name #generics {
            #(#variants_with_attrs),*
        }
    };

    result
}