Skip to content

Commit e12402c

Browse files
committed
Support omitted discriminants
Closes: #1 Signed-off-by: Anders Kaseorg <[email protected]>
1 parent 173a5a8 commit e12402c

File tree

2 files changed

+139
-24
lines changed

2 files changed

+139
-24
lines changed

src/lib.rs

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@
4444
//! enum FooBar {
4545
//! Foo = 17,
4646
//! Bar = 42,
47+
//! Baz,
4748
//! }
4849
//! }
4950
//!
5051
//! fn main() {
5152
//! assert_eq!(FooBar::from_i32(17), Some(FooBar::Foo));
5253
//! assert_eq!(FooBar::from_i32(42), Some(FooBar::Bar));
54+
//! assert_eq!(FooBar::from_i32(43), Some(FooBar::Baz));
5355
//! assert_eq!(FooBar::from_i32(91), None);
5456
//! }
5557
//! ```
@@ -63,7 +65,7 @@ pub use num::FromPrimitive;
6365
/// Helper macro for internal use by `enum_from_primitive!`.
6466
#[macro_export]
6567
macro_rules! enum_from_primitive_impl_ty {
66-
($meth:ident, $ty:ty, $name:ident, $( $variant:ident ),*) => {
68+
($meth:ident, $ty:ty, $name:ident, $( $variant:ident )*) => {
6769
#[allow(non_upper_case_globals, unused)]
6870
fn $meth(n: $ty) -> $crate::Option<Self> {
6971
$( if n == $name::$variant as $ty {
@@ -72,19 +74,19 @@ macro_rules! enum_from_primitive_impl_ty {
7274
$crate::Option::None
7375
}
7476
}
75-
}
77+
};
7678
}
7779

7880
/// Helper macro for internal use by `enum_from_primitive!`.
7981
#[macro_export]
8082
#[macro_use(enum_from_primitive_impl_ty)]
8183
macro_rules! enum_from_primitive_impl {
82-
($name:ident, $( $variant:ident ),*) => {
84+
($name:ident, $( $variant:ident )*) => {
8385
impl $crate::FromPrimitive for $name {
84-
enum_from_primitive_impl_ty! { from_i64, i64, $name, $( $variant ),* }
85-
enum_from_primitive_impl_ty! { from_u64, u64, $name, $( $variant ),* }
86+
enum_from_primitive_impl_ty! { from_i64, i64, $name, $( $variant )* }
87+
enum_from_primitive_impl_ty! { from_u64, u64, $name, $( $variant )* }
8688
}
87-
}
89+
};
8890
}
8991

9092
/// Wrap this macro around an `enum` declaration to get an
@@ -95,54 +97,104 @@ macro_rules! enum_from_primitive {
9597
(
9698
$( #[$enum_attr:meta] )*
9799
enum $name:ident {
98-
$( $( #[$variant_attr:meta] )* $variant:ident = $discriminator:expr ),*
100+
$( $( #[$variant_attr:meta] )* $variant:ident ),+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*
99101
}
100102
) => {
101103
$( #[$enum_attr] )*
102104
enum $name {
103-
$( $( #[$variant_attr] )* $variant = $discriminator ),*
105+
$( $( #[$variant_attr] )* $variant ),+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*
104106
}
105-
enum_from_primitive_impl! { $name, $($variant),* }
107+
enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
106108
};
107109

108110
(
109111
$( #[$enum_attr:meta] )*
110112
enum $name:ident {
111-
$( $( #[$variant_attr:meta] )* $variant:ident = $discriminator:expr ),*,
113+
$( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),*
112114
}
113115
) => {
114-
enum_from_primitive! {
115-
$( #[$enum_attr] )*
116-
enum $name {
117-
$( $( #[$variant_attr] )* $variant = $discriminator ),*
118-
}
116+
$( #[$enum_attr] )*
117+
enum $name {
118+
$( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),*
119+
}
120+
enum_from_primitive_impl! { $name, $( $( $variant )+ )* }
121+
};
122+
123+
(
124+
$( #[$enum_attr:meta] )*
125+
enum $name:ident {
126+
$( $( #[$variant_attr:meta] )* $variant:ident ),+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*,
127+
}
128+
) => {
129+
$( #[$enum_attr] )*
130+
enum $name {
131+
$( $( #[$variant_attr] )* $variant ),+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*,
132+
}
133+
enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
134+
};
135+
136+
(
137+
$( #[$enum_attr:meta] )*
138+
enum $name:ident {
139+
$( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+,
140+
}
141+
) => {
142+
$( #[$enum_attr] )*
143+
enum $name {
144+
$( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+,
119145
}
146+
enum_from_primitive_impl! { $name, $( $( $variant )+ )+ }
120147
};
121148

122149
(
123150
$( #[$enum_attr:meta] )*
124151
pub enum $name:ident {
125-
$( $( #[$variant_attr:meta] )* $variant:ident = $discriminator:expr ),*
152+
$( $( #[$variant_attr:meta] )* $variant:ident ),+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*
126153
}
127154
) => {
128155
$( #[$enum_attr] )*
129156
pub enum $name {
130-
$( $( #[$variant_attr] )* $variant = $discriminator ),*
157+
$( $( #[$variant_attr] )* $variant ),+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*
131158
}
132-
enum_from_primitive_impl! { $name, $( $variant ),* }
159+
enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
133160
};
134161

135162
(
136163
$( #[$enum_attr:meta] )*
137164
pub enum $name:ident {
138-
$( $( #[$variant_attr:meta] )* $variant:ident = $discriminator:expr ),*,
165+
$( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),*
139166
}
140167
) => {
141-
enum_from_primitive! {
142-
$( #[$enum_attr] )*
143-
pub enum $name {
144-
$( $( #[$variant_attr] )* $variant = $discriminator ),*
145-
}
168+
$( #[$enum_attr] )*
169+
pub enum $name {
170+
$( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),*
171+
}
172+
enum_from_primitive_impl! { $name, $( $( $variant )+ )* }
173+
};
174+
175+
(
176+
$( #[$enum_attr:meta] )*
177+
pub enum $name:ident {
178+
$( $( #[$variant_attr:meta] )* $variant:ident ),+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*,
179+
}
180+
) => {
181+
$( #[$enum_attr] )*
182+
pub enum $name {
183+
$( $( #[$variant_attr] )* $variant ),+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*,
184+
}
185+
enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
186+
};
187+
188+
(
189+
$( #[$enum_attr:meta] )*
190+
pub enum $name:ident {
191+
$( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+,
192+
}
193+
) => {
194+
$( #[$enum_attr] )*
195+
pub enum $name {
196+
$( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+,
146197
}
198+
enum_from_primitive_impl! { $name, $( $( $variant )+ )+ }
147199
};
148200
}

tests/omitted-discriminants.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#[macro_use] extern crate enum_primitive;
2+
3+
enum_from_primitive! { enum E { } }
4+
enum_from_primitive! { enum E0 { V0 } }
5+
enum_from_primitive! { enum E0C { V0, } }
6+
enum_from_primitive! { enum E1 { V0 = 0 } }
7+
enum_from_primitive! { enum E1C { V0 = 0, } }
8+
enum_from_primitive! { enum E00 { V0, V1 } }
9+
enum_from_primitive! { enum E00C { V0, V1, } }
10+
enum_from_primitive! { enum E01 { V0, V1 = 1 } }
11+
enum_from_primitive! { enum E01C { V0, V1 = 1, } }
12+
enum_from_primitive! { enum E10 { V0 = 0, V1 } }
13+
enum_from_primitive! { enum E10C { V0 = 0, V1, } }
14+
enum_from_primitive! { enum E11 { V0 = 0, V1 = 1 } }
15+
enum_from_primitive! { enum E11C { V0 = 0, V1 = 1, } }
16+
enum_from_primitive! { enum E000 { V0, V1, V2 } }
17+
enum_from_primitive! { enum E000C { V0, V1, V2, } }
18+
enum_from_primitive! { enum E001 { V0, V1, V2 = 2 } }
19+
enum_from_primitive! { enum E001C { V0, V1, V2 = 2, } }
20+
enum_from_primitive! { enum E010 { V0, V1 = 1, V2 } }
21+
enum_from_primitive! { enum E010C { V0, V1 = 1, V2, } }
22+
enum_from_primitive! { enum E011 { V0, V1 = 1, V2 = 2 } }
23+
enum_from_primitive! { enum E011C { V0, V1 = 1, V2 = 2, } }
24+
enum_from_primitive! { enum E100 { V0 = 0, V1, V2 } }
25+
enum_from_primitive! { enum E100C { V0 = 0, V1, V2, } }
26+
enum_from_primitive! { enum E101 { V0 = 0, V1, V2 = 2 } }
27+
enum_from_primitive! { enum E101C { V0 = 0, V1, V2 = 2, } }
28+
enum_from_primitive! { enum E110 { V0 = 0, V1 = 1, V2 } }
29+
enum_from_primitive! { enum E110C { V0 = 0, V1 = 1, V2, } }
30+
enum_from_primitive! { enum E111 { V0 = 0, V1 = 1, V2 = 2 } }
31+
enum_from_primitive! { enum E111C { V0 = 0, V1 = 1, V2 = 2, } }
32+
enum_from_primitive! { enum E0000 { V0, V1, V2, V3 } }
33+
enum_from_primitive! { enum E0000C { V0, V1, V2, V3, } }
34+
enum_from_primitive! { enum E0001 { V0, V1, V2, V3 = 3 } }
35+
enum_from_primitive! { enum E0001C { V0, V1, V2, V3 = 3, } }
36+
enum_from_primitive! { enum E0010 { V0, V1, V2 = 2, V3 } }
37+
enum_from_primitive! { enum E0010C { V0, V1, V2 = 2, V3, } }
38+
enum_from_primitive! { enum E0011 { V0, V1, V2 = 2, V3 = 3 } }
39+
enum_from_primitive! { enum E0011C { V0, V1, V2 = 2, V3 = 3, } }
40+
enum_from_primitive! { enum E0100 { V0, V1 = 1, V2, V3 } }
41+
enum_from_primitive! { enum E0100C { V0, V1 = 1, V2, V3, } }
42+
enum_from_primitive! { enum E0101 { V0, V1 = 1, V2, V3 = 3 } }
43+
enum_from_primitive! { enum E0101C { V0, V1 = 1, V2, V3 = 3, } }
44+
enum_from_primitive! { enum E0110 { V0, V1 = 1, V2 = 2, V3 } }
45+
enum_from_primitive! { enum E0110C { V0, V1 = 1, V2 = 2, V3, } }
46+
enum_from_primitive! { enum E0111 { V0, V1 = 1, V2 = 2, V3 = 3 } }
47+
enum_from_primitive! { enum E0111C { V0, V1 = 1, V2 = 2, V3 = 3, } }
48+
enum_from_primitive! { enum E1000 { V0 = 0, V1, V2, V3 } }
49+
enum_from_primitive! { enum E1000C { V0 = 0, V1, V2, V3, } }
50+
enum_from_primitive! { enum E1001 { V0 = 0, V1, V2, V3 = 3 } }
51+
enum_from_primitive! { enum E1001C { V0 = 0, V1, V2, V3 = 3, } }
52+
enum_from_primitive! { enum E1010 { V0 = 0, V1, V2 = 2, V3 } }
53+
enum_from_primitive! { enum E1010C { V0 = 0, V1, V2 = 2, V3, } }
54+
enum_from_primitive! { enum E1011 { V0 = 0, V1, V2 = 2, V3 = 3 } }
55+
enum_from_primitive! { enum E1011C { V0 = 0, V1, V2 = 2, V3 = 3, } }
56+
enum_from_primitive! { enum E1100 { V0 = 0, V1 = 1, V2, V3 } }
57+
enum_from_primitive! { enum E1100C { V0 = 0, V1 = 1, V2, V3, } }
58+
enum_from_primitive! { enum E1101 { V0 = 0, V1 = 1, V2, V3 = 3 } }
59+
enum_from_primitive! { enum E1101C { V0 = 0, V1 = 1, V2, V3 = 3, } }
60+
enum_from_primitive! { enum E1110 { V0 = 0, V1 = 1, V2 = 2, V3 } }
61+
enum_from_primitive! { enum E1110C { V0 = 0, V1 = 1, V2 = 2, V3, } }
62+
enum_from_primitive! { enum E1111 { V0 = 0, V1 = 1, V2 = 2, V3 = 3 } }
63+
enum_from_primitive! { enum E1111C { V0 = 0, V1 = 1, V2 = 2, V3 = 3, } }

0 commit comments

Comments
 (0)