77 lines
1.9 KiB
Rust
77 lines
1.9 KiB
Rust
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()
|
|
}
|