@@ -40,16 +40,32 @@ macro_rules! iterable_enum {
40
40
/// and EnumType.get_name() for free.
41
41
#[ macro_export]
42
42
macro_rules! define_named_enum {
43
- ( $Name: ident { $( $Variant: ident( $VarName: literal) , ) * } ) =>
44
- {
43
+ (
44
+ $( #[ $enum_meta: meta] ) *
45
+ $Name: ident {
46
+ $(
47
+ $( #[ $variant_meta: meta] ) *
48
+ $Variant: ident( $VarName: literal) ,
49
+ ) *
50
+ }
51
+ ) => {
52
+ $( #[ $enum_meta] ) *
45
53
#[ derive( :: serde:: Serialize , :: serde:: Deserialize , Debug , Hash , PartialEq , Eq , Copy , Clone ) ]
46
54
pub enum $Name {
47
- $( $Variant) ,* ,
55
+ $(
56
+ $( #[ $variant_meta] ) *
57
+ $Variant,
58
+ ) *
48
59
}
60
+
49
61
impl $Name {
62
+ /// All variants of the enum.
50
63
pub const ALL : & [ $Name] = & [ $( $Name:: $Variant) ,* ] ;
64
+
65
+ /// All names corresponding to the enum variants.
51
66
pub const ALL_NAMES : & [ & str ] = & [ $( $VarName) ,* ] ;
52
67
68
+ /// Looks up a variant by its name string.
53
69
pub fn lookup_by_name( name: & str ) -> Option <Self > {
54
70
match name {
55
71
$(
@@ -59,6 +75,7 @@ macro_rules! define_named_enum {
59
75
}
60
76
}
61
77
78
+ /// Gets the name of the enum variant as a `String`.
62
79
pub fn get_name( & self ) -> String {
63
80
match self {
64
81
$(
@@ -67,6 +84,7 @@ macro_rules! define_named_enum {
67
84
}
68
85
}
69
86
87
+ /// Gets the name of the enum variant as a static string slice.
70
88
pub fn get_name_str( & self ) -> & ' static str {
71
89
match self {
72
90
$(
@@ -75,12 +93,13 @@ macro_rules! define_named_enum {
75
93
}
76
94
}
77
95
}
96
+
78
97
impl :: std:: fmt:: Display for $Name {
79
98
fn fmt( & self , f: & mut :: std:: fmt:: Formatter <' _>) -> :: std:: fmt:: Result {
80
99
write!( f, "{}" , self . get_name_str( ) )
81
100
}
82
101
}
83
- }
102
+ } ;
84
103
}
85
104
86
105
/// Define a "named" enum, i.e., each variant corresponds
@@ -739,3 +758,46 @@ macro_rules! function_name {
739
758
stdext:: function_name!( )
740
759
} ;
741
760
}
761
+
762
+ #[ cfg( test) ]
763
+ mod tests {
764
+ #[ test]
765
+ fn test_macro_define_named_enum_without_docs ( ) {
766
+ define_named_enum ! (
767
+ MyEnum {
768
+ Variant1 ( "variant1" ) ,
769
+ Variant2 ( "variant2" ) ,
770
+ } ) ;
771
+
772
+ assert_eq ! ( "variant1" , MyEnum :: Variant1 . get_name( ) ) ;
773
+ assert_eq ! ( "variant2" , MyEnum :: Variant2 . get_name( ) ) ;
774
+
775
+ assert_eq ! ( "variant1" , MyEnum :: Variant1 . get_name_str( ) ) ;
776
+ assert_eq ! ( "variant2" , MyEnum :: Variant2 . get_name_str( ) ) ;
777
+
778
+ assert_eq ! ( Some ( MyEnum :: Variant1 ) , MyEnum :: lookup_by_name( "variant1" ) ) ;
779
+ assert_eq ! ( Some ( MyEnum :: Variant2 ) , MyEnum :: lookup_by_name( "variant2" ) ) ;
780
+ assert_eq ! ( None , MyEnum :: lookup_by_name( "inexistent" ) ) ;
781
+ }
782
+ #[ test]
783
+ fn test_macro_define_named_enum_with_docs ( ) {
784
+ define_named_enum ! (
785
+ /// MyEnum doc
786
+ MyEnum {
787
+ /// Variant1 doc
788
+ Variant1 ( "variant1" ) ,
789
+ /// Variant2 doc
790
+ Variant2 ( "variant2" ) ,
791
+ } ) ;
792
+
793
+ assert_eq ! ( "variant1" , MyEnum :: Variant1 . get_name( ) ) ;
794
+ assert_eq ! ( "variant2" , MyEnum :: Variant2 . get_name( ) ) ;
795
+
796
+ assert_eq ! ( "variant1" , MyEnum :: Variant1 . get_name_str( ) ) ;
797
+ assert_eq ! ( "variant2" , MyEnum :: Variant2 . get_name_str( ) ) ;
798
+
799
+ assert_eq ! ( Some ( MyEnum :: Variant1 ) , MyEnum :: lookup_by_name( "variant1" ) ) ;
800
+ assert_eq ! ( Some ( MyEnum :: Variant2 ) , MyEnum :: lookup_by_name( "variant2" ) ) ;
801
+ assert_eq ! ( None , MyEnum :: lookup_by_name( "inexistent" ) ) ;
802
+ }
803
+ }
0 commit comments