1#![cfg_attr(not(test), no_std)]
2
3#[macro_export]
35macro_rules! fake_enum{
36 {#[repr($tvis:vis $t:ty)] $(#[$meta:meta])* $vis:vis enum $name:ident {
37 $(#![$meta1:meta])*
38 $($(#[$r:meta])* $item:ident = $expr:literal),*$(,)?
39 }} => {
40
41 #[derive(Copy,Clone,Eq,PartialEq)]
42 #[repr(transparent)]
43 $(#[$meta])*
44 $(#[$meta1])*
45 $vis struct $name($tvis $t);
46
47 $(#[allow(non_upper_case_globals)] #[allow(dead_code)] $(#[$r])* $vis const $item: $name = $name($expr as $t);)*
48
49 impl ::core::fmt::Debug for $name{
50 #[allow(unreachable_patterns)]
51 fn fmt(&self,f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result{
52 match self{
53 $(Self($expr) => f.write_str(::core::stringify!($item)),)*
54 e => f.write_fmt(::core::format_args!("{}({})",::core::stringify!($name),e.0))
55 }
56 }
57 }
58 };
59 {#[repr($tvis:vis $t:ty)] $(#[$meta:meta])* $vis:vis enum struct $name:ident {
60 $(#![$meta1:meta])*
61 $($(#[$r:meta])* $item:ident = $expr:literal),*$(,)?
62 }} => {
63 #[derive(Copy,Clone,Eq,PartialEq)]
64 #[repr(transparent)]
65 $(#[$meta])*
66 $(#[$meta1])*
67 $vis struct $name($tvis $t);
68 impl $name{
69 $(#[allow(non_upper_case_globals)] #[allow(dead_code)] $(#[$r])* pub const $item: $name = $name($expr as $t);)*
70 }
71 impl ::core::fmt::Debug for $name{
72 #[allow(unreachable_patterns)]
73 fn fmt(&self,f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result{
74 match self{
75 $(Self($expr) => f.write_str(::core::stringify!($item)),)*
76 e => f.write_fmt(::core::format_args!("{}({})",::core::stringify!($name),e.0))
77 }
78 }
79 }
80 }
81}
82
83#[cfg(test)]
84mod test {
85 fake_enum! {
86 #[repr(u16)] pub enum ElfType{
87 ET_NONE = 0,
91 ET_REL = 1,
93 ET_EXEC = 2,
95 ET_DYN = 3,
97 ET_CORE = 4
99 }
100 }
101
102 #[test]
103 pub fn fake_enum_elf_type_name() {
104 assert_eq!(format!("{:?}", ET_NONE), "ET_NONE");
105 assert_eq!(format!("{:?}", ET_REL), "ET_REL");
106 assert_eq!(format!("{:?}", ET_EXEC), "ET_EXEC");
107 assert_eq!(format!("{:?}", ET_DYN), "ET_DYN");
108 assert_eq!(format!("{:?}", ET_CORE), "ET_CORE");
109 }
110
111 #[test]
112 pub fn fake_enum_partial_eq_impl() {
113 assert_eq!(ET_NONE, ET_NONE);
114 assert_ne!(ET_NONE, ET_REL);
115 assert_ne!(ET_NONE, ET_EXEC);
116 assert_ne!(ET_NONE, ET_DYN);
117 assert_ne!(ET_NONE, ET_CORE);
118 assert_eq!(ET_REL, ET_REL);
119 assert_ne!(ET_REL, ET_EXEC);
120 assert_ne!(ET_REL, ET_DYN);
121 assert_ne!(ET_REL, ET_CORE);
122 assert_eq!(ET_EXEC, ET_EXEC);
123 assert_ne!(ET_EXEC, ET_DYN);
124 assert_ne!(ET_EXEC, ET_CORE);
125 assert_eq!(ET_DYN, ET_DYN);
126 assert_ne!(ET_DYN, ET_CORE);
127 assert_eq!(ET_CORE, ET_CORE);
128 }
129
130 #[test]
131 pub fn fake_enum_transmute_test() {
132 assert_eq!(unsafe { std::mem::transmute::<u16, ElfType>(0) }, ET_NONE);
133 assert_eq!(unsafe { std::mem::transmute::<u16, ElfType>(1) }, ET_REL);
134 assert_eq!(unsafe { std::mem::transmute::<u16, ElfType>(2) }, ET_EXEC);
135 assert_eq!(unsafe { std::mem::transmute::<u16, ElfType>(3) }, ET_DYN);
136 assert_eq!(unsafe { std::mem::transmute::<u16, ElfType>(4) }, ET_CORE);
137 }
138
139 fake_enum! {
140 #[repr(u8)]
141 #[derive(Hash,Default)]
142 pub enum struct NbtTagType{
143 End = 0,
147 Byte = 1,
149 Short = 2,
151 Int = 3,
153 Long = 4,
155 Float = 5,
157 Double = 6,
158 ByteArray = 7,
159 String = 8,
160 List = 9,
161 Compound = 10,
162 IntArray = 11,
163 LongArray = 12,
164 FloatArray = 13,
165 DoubleArray = 14,
166 Uuid = 15
167 }
168 }
169
170 fake_enum! {
171 #[repr(pub u8)]
172 pub enum struct Test{
173 Foo = 0
174 }
175 }
176
177 #[test]
178 fn pub_repr_test() {
179 let foo = Test(0);
180 assert_eq!(foo, Test::Foo);
181 }
182}