@@ -27,40 +27,85 @@ impl<T: Into<u8>> From<ByteWrapper<T>> for u8 {
27
27
}
28
28
}
29
29
30
- impl < T : TryFrom < u8 > > From < u8 > for ByteWrapper < T > {
31
- fn from ( value : u8 ) -> Self {
32
- match T :: try_from ( value) {
33
- Ok ( v) => ByteWrapper :: Standard ( v) ,
34
- Err ( _) => ByteWrapper :: Extended ( value) ,
35
- }
36
- }
37
- }
38
-
39
- #[ macro_export]
40
30
macro_rules! enum_wrapper {
41
31
( $ns: tt, $enum_name: tt, $enum_wrapper: tt) => {
42
- #[ doc = concat!( "Store a single byte, either as a `Standard(" , stringify!( $enum_name) , ")`, or as an `Extended(u8)`." ) ]
43
- pub type $enum_wrapper = $crate:: ByteWrapper <$enum_name>;
32
+ $crate:: utils:: enum_impls!( $ns, $enum_name) ;
33
+ $crate:: utils:: enum_byte_wrapper!( $ns, $enum_name, $enum_wrapper) ;
34
+ } ;
35
+ }
44
36
45
- impl From <$crate:: $ns:: $enum_name> for $crate:: $ns:: $enum_wrapper {
37
+ macro_rules! enum_impls {
38
+ ( $ns: tt, $enum_name: tt) => {
39
+ impl TryFrom <u8 > for $crate:: $ns:: $enum_name {
40
+ type Error = & ' static str ;
41
+ fn try_from( value: u8 ) -> Result <Self , Self :: Error > {
42
+ $crate:: $ns:: $enum_name:: from_repr( value)
43
+ . ok_or( "Failed to convert enum to numeric value!" )
44
+ }
45
+ }
46
+
47
+ impl From <$crate:: $ns:: $enum_name> for u8 {
46
48
fn from( value: $crate:: $ns:: $enum_name) -> Self {
47
- Self :: Standard ( value)
49
+ value as Self
48
50
}
49
51
}
50
52
51
53
#[ cfg( test) ]
52
- mod enum_wrapper_tests {
54
+ mod enum_impls_tests {
53
55
#[ test]
54
- #[ allow( non_snake_case) ]
55
56
fn test_try_from( ) {
56
57
for value in 0x00_u8 ..=0xFF {
57
58
if let Ok ( v) = $crate:: $ns:: $enum_name:: try_from( value) {
58
59
let enc: u8 = v. into( ) ;
59
60
assert_eq!( value, enc, "{value:#02X} → {v:?} → {enc:#02X}" ) ;
61
+ assert_eq!(
62
+ $crate:: $ns:: $enum_name:: from_repr( value) . unwrap( ) ,
63
+ v,
64
+ "{value:#02X} → {v:?}"
65
+ ) ;
60
66
}
61
67
}
62
68
}
63
69
70
+ #[ test]
71
+ #[ cfg( feature = "iter" ) ]
72
+ fn test_iter( ) {
73
+ use :: strum:: IntoEnumIterator as _;
74
+
75
+ assert_ne!( 0 , $crate:: $ns:: $enum_name:: iter( ) . count( ) ) ;
76
+ for value in $crate:: $ns:: $enum_name:: iter( ) {
77
+ let enc: u8 = value. into( ) ;
78
+ assert_eq!( value, $crate:: $ns:: $enum_name:: try_from( enc) . unwrap( ) ) ;
79
+ }
80
+ }
81
+ }
82
+ } ;
83
+ }
84
+
85
+ macro_rules! enum_byte_wrapper {
86
+ ( $ns: tt, $enum_name: tt, $enum_wrapper: tt) => {
87
+ #[ doc = concat!( "Store a single byte, either as a `Standard(" , stringify!( $enum_name) , ")`, or as an `Extended(u8)`." ) ]
88
+ pub type $enum_wrapper = $crate:: ByteWrapper <$enum_name>;
89
+
90
+ impl From <$crate:: $ns:: $enum_name> for $crate:: $ns:: $enum_wrapper {
91
+ fn from( value: $crate:: $ns:: $enum_name) -> Self {
92
+ Self :: Standard ( value)
93
+ }
94
+ }
95
+
96
+ // Implementing it as part of the macro because from_repr is not part of a trait
97
+ // https://github.com/Peternator7/strum/issues/251
98
+ impl From <u8 > for $crate:: ByteWrapper <$crate:: $ns:: $enum_name> {
99
+ fn from( value: u8 ) -> Self {
100
+ match $crate:: $ns:: $enum_name:: from_repr( value) {
101
+ Some ( v) => $crate:: ByteWrapper :: Standard ( v) ,
102
+ None => $crate:: ByteWrapper :: Extended ( value) ,
103
+ }
104
+ }
105
+ }
106
+
107
+ #[ cfg( test) ]
108
+ mod enum_byte_wrapper_tests {
64
109
#[ test]
65
110
#[ allow( non_snake_case) ]
66
111
fn test_from( ) {
@@ -73,3 +118,5 @@ macro_rules! enum_wrapper {
73
118
}
74
119
} ;
75
120
}
121
+
122
+ pub ( crate ) use { enum_byte_wrapper, enum_impls, enum_wrapper} ;
0 commit comments