Skip to content

Commit 330795e

Browse files
authored
Merge pull request #75 from hashmismatch/primitive_enum_roundtrip
Primitive Enums roundtrip tests and fixes
2 parents 7cf40ed + f82c2b8 commit 330795e

File tree

2 files changed

+120
-6
lines changed

2 files changed

+120
-6
lines changed

packed_struct_codegen/src/primitive_enum.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ fn get_unitary_enum(input: &syn::DeriveInput) -> syn::Result<Vec<Variant>> {
230230

231231
let mut r = Vec::new();
232232

233-
let mut d = 0;
233+
let mut d: Option<u64> = None;
234234
let mut neg = false;
235235

236236
for variant in &data_enum.variants {
@@ -265,10 +265,15 @@ fn get_unitary_enum(input: &syn::DeriveInput) -> syn::Result<Vec<Variant>> {
265265
return Err(syn::Error::new(variant.span(), "Unsupported enum const expr"));
266266
},
267267
None => {
268-
if neg {
269-
(d-1, if d-1 == 0 { false } else { true }, "".into())
270-
} else {
271-
(d+1, false, "".into())
268+
match d {
269+
None => (0, false, "".into()),
270+
Some(d) => {
271+
if neg {
272+
(d-1, if d-1 == 0 { false } else { true }, "".into())
273+
} else {
274+
(d+1, false, "".into())
275+
}
276+
}
272277
}
273278
}
274279
};
@@ -280,7 +285,7 @@ fn get_unitary_enum(input: &syn::DeriveInput) -> syn::Result<Vec<Variant>> {
280285
suffix
281286
});
282287

283-
d = discriminant;
288+
d = Some(discriminant);
284289
neg = negative;
285290
}
286291

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use std::any::type_name;
2+
3+
use packed_struct::{PrimitiveEnumStaticStr, prelude::*};
4+
5+
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
6+
pub enum EnumImplicit {
7+
Zero,
8+
One,
9+
Two,
10+
Three
11+
}
12+
13+
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
14+
pub enum EnumExplicit {
15+
Zero = 0,
16+
One,
17+
Two,
18+
Three
19+
}
20+
21+
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
22+
pub enum EnumExplicitHalf {
23+
Zero,
24+
One = 1,
25+
Two,
26+
Three
27+
}
28+
29+
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
30+
pub enum EnumExplicitHalfZero {
31+
Zero = 0,
32+
One,
33+
Two = 2,
34+
Three
35+
}
36+
37+
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
38+
pub enum EnumExplicitFull {
39+
Zero = 0,
40+
One = 1,
41+
Two = 2,
42+
Three = 3
43+
}
44+
45+
#[derive(PrimitiveEnum_i8, Clone, Copy, Debug, PartialEq)]
46+
pub enum EnumExplicitNegative {
47+
MinusTwo = -2,
48+
MinusOne = -1,
49+
Zero,
50+
One = 1,
51+
Two = 2
52+
}
53+
54+
#[derive(PrimitiveEnum_i8, Clone, Copy, Debug, PartialEq)]
55+
pub enum EnumExplicitNegativeOne {
56+
MinusOne = -1,
57+
Zero,
58+
One,
59+
Two
60+
}
61+
62+
63+
#[derive(PrimitiveEnum_i8, Clone, Copy, Debug, PartialEq)]
64+
pub enum EnumExplicitNegativeTwo {
65+
MinusTwo = -2,
66+
MinusOne,
67+
Zero,
68+
One,
69+
Two
70+
}
71+
72+
#[test]
73+
fn prim() {
74+
test_enum_positive::<EnumImplicit>();
75+
test_enum_positive::<EnumExplicit>();
76+
test_enum_positive::<EnumExplicitHalf>();
77+
test_enum_positive::<EnumExplicitHalfZero>();
78+
79+
test_enum_negative::<EnumExplicitNegative>();
80+
test_enum_negative::<EnumExplicitNegativeOne>();
81+
test_enum_negative::<EnumExplicitNegativeTwo>();
82+
}
83+
84+
fn test_enum_positive<E: PrimitiveEnum<Primitive = u8> + PrimitiveEnumStaticStr + std::fmt::Debug + PartialEq + 'static>() {
85+
for (i, x) in E::all_variants().iter().enumerate() {
86+
let prim = x.to_primitive();
87+
assert_eq!(prim, i as u8);
88+
89+
let from_prim = E::from_primitive(prim).expect(&format!("Expected a successful parse of {}, ty {}", prim, type_name::<E>()));
90+
assert_eq!(from_prim, *x);
91+
92+
let display_str = x.to_display_str();
93+
let from_display_str = E::from_str(display_str).expect(&format!("Expected a successful parse of display string {}, ty {}", display_str, type_name::<E>()));
94+
assert_eq!(from_display_str, *x);
95+
}
96+
}
97+
98+
fn test_enum_negative<E: PrimitiveEnum<Primitive = i8> + PrimitiveEnumStaticStr + std::fmt::Debug + PartialEq + 'static>() {
99+
for x in E::all_variants().iter() {
100+
let prim = x.to_primitive();
101+
102+
let from_prim = E::from_primitive(prim).expect(&format!("Expected a successful parse of {}, ty {}", prim, type_name::<E>()));
103+
assert_eq!(from_prim, *x);
104+
105+
let display_str = x.to_display_str();
106+
let from_display_str = E::from_str(display_str).expect(&format!("Expected a successful parse of display string {}, ty {}", display_str, type_name::<E>()));
107+
assert_eq!(from_display_str, *x);
108+
}
109+
}

0 commit comments

Comments
 (0)