mod macro_models; use crate::macro_models::DisplayStyleArgs; use darling::FromVariant; use quote::quote; use syn::{Data, DeriveInput, parse_macro_input}; /// Derive macro for generating a `to_display_str` method for an enum. /// /// # Example /// /// Using default values for the display style: /// /// ``` /// use enum_display_style_derive::EnumDisplayStyle; /// /// #[derive(EnumDisplayStyle)] /// enum Weekend { /// Saturday, /// Sunday, /// } /// /// assert_eq!(Weekend::Saturday.to_display_str(), "Saturday"); /// assert_eq!(Weekend::Sunday.to_display_str(), "Sunday"); /// ``` /// /// Using custom values for the display style: /// /// ``` /// use enum_display_style_derive::EnumDisplayStyle; /// /// #[derive(EnumDisplayStyle)] /// enum MonitorStatus { /// #[display_style(name = "Monitor Transactions")] /// Active, /// #[display_style(name = "Don't Monitor Transactions")] /// None, /// } /// /// assert_eq!(MonitorStatus::Active.to_display_str(), "Monitor Transactions"); /// assert_eq!(MonitorStatus::None.to_display_str(), "Don't Monitor Transactions"); /// ``` #[proc_macro_derive(EnumDisplayStyle, attributes(display_style))] pub fn enum_display_style_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as DeriveInput); let enum_name = &input.ident; let mut match_arms = Vec::new(); if let Data::Enum(data_enum) = &input.data { let variants = &data_enum.variants; for variant in variants { let variant_ident = &variant.ident; let variant_display_name = DisplayStyleArgs::from_variant(variant) .unwrap() .name .unwrap_or_else(|| variant_ident.to_string()); match_arms.push(quote! { #enum_name::#variant_ident => #variant_display_name, }); } } quote! { impl<'a> #enum_name { pub fn to_display_str(self) -> &'a str { match self { #(#match_arms)* } } } } .into() }