From 69794f0e88457e59b37bd208e32a1b58cbe457f8 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 13 Apr 2026 21:45:46 +0800 Subject: Add enum_rename attribute to EnumTag macro --- mingling_macros/src/enum_tag.rs | 52 +++++++++++++++++++++++++++++++++++++---- mingling_macros/src/lib.rs | 2 +- 2 files changed, 49 insertions(+), 5 deletions(-) (limited to 'mingling_macros') diff --git a/mingling_macros/src/enum_tag.rs b/mingling_macros/src/enum_tag.rs index 497bc88..6a3abf8 100644 --- a/mingling_macros/src/enum_tag.rs +++ b/mingling_macros/src/enum_tag.rs @@ -3,7 +3,8 @@ //! This module provides the `#[derive(EnumTag)]` procedural macro for enums. //! The macro generates implementations of the `EnumTag` trait for enums with //! unit variants only (no fields). Variants can have an optional `#[enum_desc]` -//! attribute to provide descriptions. +//! attribute to provide descriptions, and an optional `#[enum_rename]` attribute +//! to rename the variant for building and listing purposes. use proc_macro::TokenStream; use proc_macro2::Span; @@ -118,20 +119,24 @@ fn process_variant( // Extract description from #[enum_desc] attribute let description = extract_description(&variant.attrs, &variant_name)?; + // Extract rename from #[enum_rename] attribute + let rename = extract_rename(&variant.attrs)?; + // Generate tokens for this variant let variant_name_str = variant_name.to_string(); + let display_name = rename.unwrap_or_else(|| variant_name_str.clone()); let description_str = description.value(); variant_info.push(quote! { - (#variant_name_str, #description_str) + (#display_name, #description_str) }); match_arms.push(quote! { - #enum_name::#variant_name => (#variant_name_str, #description_str), + #enum_name::#variant_name => (#display_name, #description_str), }); build_match_arms.push(quote! { - #variant_name_str => Some(#enum_name::#variant_name), + #display_name => Some(#enum_name::#variant_name), }); Ok(()) @@ -165,3 +170,42 @@ fn extract_description(attrs: &[Attribute], variant_name: &Ident) -> Result Result> { + for attr in attrs { + if attr.path().is_ident("enum_rename") { + return match attr.parse_args::() { + Ok(Meta::NameValue(MetaNameValue { + path, + value: + Expr::Lit(syn::PatLit { + lit: Lit::Str(lit_str), + .. + }), + .. + })) => { + if path.is_ident("name") { + Ok(Some(lit_str.value())) + } else { + Err(Error::new_spanned( + attr, + "#[enum_rename] attribute must be in the form `#[enum_rename(name = \"new_name\")]`", + )) + } + } + Ok(_) => Err(Error::new_spanned( + attr, + "#[enum_rename] attribute must be in the form `#[enum_rename(name = \"new_name\")]`", + )), + Err(_) => Err(Error::new_spanned( + attr, + "Failed to parse #[enum_rename] attribute", + )), + }; + } + } + + // If no #[enum_rename] attribute, return None + Ok(None) +} diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs index a989ce3..da431d5 100644 --- a/mingling_macros/src/lib.rs +++ b/mingling_macros/src/lib.rs @@ -99,7 +99,7 @@ pub fn derive_groupped(input: TokenStream) -> TokenStream { groupped::derive_groupped(input) } -#[proc_macro_derive(EnumTag, attributes(enum_desc))] +#[proc_macro_derive(EnumTag, attributes(enum_desc, enum_rename))] pub fn derive_enum_tag(input: TokenStream) -> TokenStream { enum_tag::derive_enum_tag(input) } -- cgit