diff --git a/strum/src/lib.rs b/strum/src/lib.rs index 67f33ab0..fb36882f 100644 --- a/strum/src/lib.rs +++ b/strum/src/lib.rs @@ -40,7 +40,7 @@ //! | [Display] | Converts enum variants to strings | //! | [AsRefStr] | Converts enum variants to `&'static str` | //! | [IntoStaticStr] | Implements `From for &'static str` on an enum | -//! | [EnumVariantNames] | Adds a `variants` method returning an array of discriminant names | +//! | [EnumVariantNames] | Implements Strum::VariantNames which adds a static `variants` method returning an array of discriminant names | //! | [EnumIter] | Creates a new type that iterates of the variants of an enum. | //! | [EnumProperty] | Add custom properties to enum variants. | //! | [EnumMessage] | Add a verbose message to an enum variant. | @@ -218,6 +218,12 @@ pub trait EnumCount { fn count() -> usize; } +/// A trait for retrieving the names of each variant in Enum. This trait can +/// be autoderived by `strum_macros`. +pub trait VariantNames { + fn variants() -> &'static [&'static str]; +} + #[cfg(feature = "derive")] #[allow(unused_imports)] #[macro_use] diff --git a/strum_macros/src/macros/enum_variant_names.rs b/strum_macros/src/macros/enum_variant_names.rs index a1d436d6..0bc550e2 100644 --- a/strum_macros/src/macros/enum_variant_names.rs +++ b/strum_macros/src/macros/enum_variant_names.rs @@ -1,11 +1,12 @@ use proc_macro2::TokenStream; use syn; -use crate::helpers::case_style::CaseStyle; -use crate::helpers::{extract_meta, CaseStyleHelpers, MetaIteratorHelpers}; +use crate::helpers::{case_style::CaseStyle, extract_meta, CaseStyleHelpers, MetaIteratorHelpers}; pub fn enum_variant_names_inner(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; + let gen = &ast.generics; + let (impl_generics, ty_generics, where_clause) = gen.split_for_impl(); let variants = match ast.data { syn::Data::Enum(ref v) => &v.variants, @@ -24,10 +25,10 @@ pub fn enum_variant_names_inner(ast: &syn::DeriveInput) -> TokenStream { .collect::>(); quote! { - impl #name { + impl #impl_generics ::strum::VariantNames for #name #ty_generics #where_clause { /// Return a slice containing the names of the variants of this enum #[allow(dead_code)] - pub fn variants() -> &'static [&'static str] { + fn variants() -> &'static [&'static str] { &[ #(#names),* ] diff --git a/strum_tests/tests/enum_variant_names.rs b/strum_tests/tests/enum_variant_names.rs index 957c14b3..f5f78ceb 100644 --- a/strum_tests/tests/enum_variant_names.rs +++ b/strum_tests/tests/enum_variant_names.rs @@ -3,6 +3,7 @@ extern crate strum_macros; #[macro_use] extern crate structopt; extern crate strum; +use strum::VariantNames; #[test] fn simple() { @@ -17,6 +18,23 @@ fn simple() { assert_eq!(&Color::variants(), &["Red", "Blue", "Yellow"]); } +#[test] +fn variant_names_trait() { + #[allow(dead_code)] + #[derive(EnumVariantNames)] + enum Color { + Red, + Blue, + Yellow, + } + + fn generic_function() { + assert_eq!(T::variants(), &["Red", "Blue", "Yellow"]); + } + + generic_function::(); +} + #[test] fn plain_kebab() { #[allow(dead_code)]