1extern crate num_traits;
6
7pub use enum_iterator;
8pub use num_traits::{FromPrimitive, ToPrimitive};
9
10pub trait EnumUnitary : Clone
18 + Into <i64> + Into <u64> + Into <isize> + Into <usize>
23 + ToPrimitive + FromPrimitive + enum_iterator::Sequence
24{ }
25
26#[macro_export]
75macro_rules! enum_unitary {
76 (
80 $(#[$attrs:meta])*
81 enum $enum:ident { $($variant:ident),* }
82 ) => {
83 $(#[$attrs])*
84 #[derive(Clone, $crate::enum_iterator::Sequence)]
85 enum $enum {
86 $($variant),*
87 }
88
89 impl From <$enum> for isize {
90 fn from (x : $enum) -> Self {
91 x as isize
92 }
93 }
94 impl From <$enum> for usize {
95 fn from (x : $enum) -> Self {
96 x as usize
97 }
98 }
99 impl From <$enum> for i64 {
100 fn from (x : $enum) -> Self {
101 x as i64
102 }
103 }
104 impl From <$enum> for u64 {
105 fn from (x : $enum) -> Self {
106 x as u64
107 }
108 }
109
110 impl $crate::FromPrimitive for $enum {
111 fn from_i64 (x : i64) -> Option <Self> {
112 const VARIANTS : [$enum; $crate::enum_iterator::cardinality::<$enum>()]
113 = [$($enum::$variant),*];
114 VARIANTS.get (x as usize).cloned()
115 }
116 fn from_u64 (x : u64) -> Option <Self> {
117 const VARIANTS : [$enum; $crate::enum_iterator::cardinality::<$enum>()]
118 = [$($enum::$variant),*];
119 VARIANTS.get (x as usize).cloned()
120 }
121 }
122
123 impl $crate::ToPrimitive for $enum {
124 fn to_i64 (&self) -> Option <i64> {
125 Some (self.clone() as i64)
126 }
127 fn to_u64 (&self) -> Option <u64> {
128 Some (self.clone() as u64)
129 }
130 }
131
132 impl $crate::EnumUnitary for $enum { }
133 };
134
135 (
139 $(#[$attrs:meta])*
140 pub enum $enum:ident { $($variant:ident),* }
141 ) => {
142 $(#[$attrs])*
143 #[derive(Clone, $crate::enum_iterator::Sequence)]
144 pub enum $enum {
145 $($variant),*
146 }
147
148 impl From <$enum> for isize {
149 fn from (x : $enum) -> Self {
150 x as isize
151 }
152 }
153 impl From <$enum> for usize {
154 fn from (x: $enum) -> Self {
155 x as usize
156 }
157 }
158 impl From <$enum> for i64 {
159 fn from (x : $enum) -> Self {
160 x as i64
161 }
162 }
163 impl From <$enum> for u64 {
164 fn from (x: $enum) -> Self {
165 x as u64
166 }
167 }
168
169 impl $crate::FromPrimitive for $enum {
170 fn from_i64 (x : i64) -> Option <Self> {
171 const VARIANTS : [$enum; $crate::enum_iterator::cardinality::<$enum>()]
172 = [$($enum::$variant),*];
173 VARIANTS.get (x as usize).cloned()
174 }
175 fn from_u64 (x: u64) -> Option <Self> {
176 const VARIANTS : [$enum; $crate::enum_iterator::cardinality::<$enum>()]
177 = [$($enum::$variant),*];
178 VARIANTS.get (x as usize).cloned()
179 }
180 }
181
182 impl $crate::ToPrimitive for $enum {
183 fn to_i64 (&self) -> Option <i64> {
184 Some (self.clone() as i64)
185 }
186 fn to_u64 (&self) -> Option <u64> {
187 Some (self.clone() as u64)
188 }
189 }
190
191 impl $crate::EnumUnitary for $enum { }
192 };
193}
194
195#[cfg(doc)]
199enum_unitary!{
200 pub enum Example {
202 A, B, C
203 }
204}
205
206#[cfg(test)]
210mod tests {
211 #[test]
212 fn test_unit() {
213 use crate::{FromPrimitive, ToPrimitive};
214
215 enum_unitary!{
217 #[derive(Debug, PartialEq)]
218 enum Myenum1 {
219 A, B, C
220 }
221 }
222 assert_eq!(enum_iterator::cardinality::<Myenum1>(), 3);
223 assert_eq!(Into::<usize>::into (Myenum1::A), 0);
224 assert_eq!(Into::<usize>::into (Myenum1::B), 1);
225 assert_eq!(Into::<usize>::into (Myenum1::C), 2);
226 assert_eq!(Some (Myenum1::A), Myenum1::from_usize (0));
227 assert_eq!(Some (Myenum1::B), Myenum1::from_usize (1));
228 assert_eq!(Some (Myenum1::C), Myenum1::from_usize (2));
229 assert_eq!(None, Myenum1::from_usize (3));
230 assert_eq!(Some (0), Myenum1::A.to_usize());
231 assert_eq!(Some (1), Myenum1::B.to_usize());
232 assert_eq!(Some (2), Myenum1::C.to_usize());
233 assert_eq!(enum_iterator::first::<Myenum1>().unwrap(), Myenum1::A);
234 assert_eq!(enum_iterator::last::<Myenum1>().unwrap(), Myenum1::C);
235 let mut i = enum_iterator::all::<Myenum1>();
236 assert_eq!(i.next(), Some (Myenum1::A));
237 assert_eq!(i.next(), Some (Myenum1::B));
238 assert_eq!(i.next(), Some (Myenum1::C));
239 assert_eq!(i.next(), None);
240 assert_eq!(enum_iterator::next (&Myenum1::A), Some (Myenum1::B));
241 assert_eq!(enum_iterator::previous (&Myenum1::A), None);
242 assert_eq!(enum_iterator::next (&Myenum1::B), Some (Myenum1::C));
243 assert_eq!(enum_iterator::previous (&Myenum1::B), Some (Myenum1::A));
244 assert_eq!(enum_iterator::next (&Myenum1::C), None);
245 assert_eq!(enum_iterator::previous (&Myenum1::C), Some (Myenum1::B));
246
247 enum_unitary!{
249 #[derive(Debug, PartialEq)]
250 pub enum Myenum2 {
251 A, B, C
252 }
253 }
254 assert_eq!(enum_iterator::cardinality::<Myenum2>(), 3);
255 assert_eq!(Into::<usize>::into (Myenum2::A), 0);
256 assert_eq!(Into::<usize>::into (Myenum2::B), 1);
257 assert_eq!(Into::<usize>::into (Myenum2::C), 2);
258 assert_eq!(Some (Myenum2::A), Myenum2::from_usize (0));
259 assert_eq!(Some (Myenum2::B), Myenum2::from_usize (1));
260 assert_eq!(Some (Myenum2::C), Myenum2::from_usize (2));
261 assert_eq!(None, Myenum2::from_usize (3));
262 assert_eq!(Some (0), Myenum2::A.to_usize());
263 assert_eq!(Some (1), Myenum2::B.to_usize());
264 assert_eq!(Some (2), Myenum2::C.to_usize());
265 assert_eq!(enum_iterator::first::<Myenum2>().unwrap(), Myenum2::A);
266 assert_eq!(enum_iterator::last::<Myenum2>().unwrap(), Myenum2::C);
267 let mut i = enum_iterator::all::<Myenum2>();
268 assert_eq!(i.next(), Some (Myenum2::A));
269 assert_eq!(i.next(), Some (Myenum2::B));
270 assert_eq!(i.next(), Some (Myenum2::C));
271 assert_eq!(i.next(), None);
272 assert_eq!(enum_iterator::next (&Myenum2::A), Some (Myenum2::B));
273 assert_eq!(enum_iterator::previous (&Myenum2::A), None);
274 assert_eq!(enum_iterator::next (&Myenum2::B), Some (Myenum2::C));
275 assert_eq!(enum_iterator::previous (&Myenum2::B), Some (Myenum2::A));
276 assert_eq!(enum_iterator::next (&Myenum2::C), None);
277 assert_eq!(enum_iterator::previous (&Myenum2::C), Some (Myenum2::B));
278
279 enum_unitary!{
281 #[derive(Debug, PartialEq)]
282 enum Myenum3 {
283 X
284 }
285 }
286 assert_eq!(enum_iterator::cardinality::<Myenum3>(), 1);
287 assert_eq!(Into::<usize>::into (Myenum3::X), 0);
288 assert_eq!(Some (Myenum3::X), Myenum3::from_usize (0));
289 assert_eq!(None, Myenum3::from_usize (1));
290 assert_eq!(Some (0), Myenum3::X.to_usize());
291 assert_eq!(enum_iterator::first::<Myenum3>().unwrap(), Myenum3::X);
292 assert_eq!(enum_iterator::last::<Myenum3>().unwrap(), Myenum3::X);
293 let mut i = enum_iterator::all::<Myenum3>();
294 assert_eq!(i.next(), Some (Myenum3::X));
295 assert_eq!(i.next(), None);
296 assert_eq!(enum_iterator::next (&Myenum3::X), None);
297 assert_eq!(enum_iterator::previous (&Myenum3::X), None);
298
299 enum_unitary!{
301 #[derive(Debug, PartialEq)]
302 pub enum Myenum4 {
303 X
304 }
305 }
306 assert_eq!(enum_iterator::cardinality::<Myenum4>(), 1);
307 assert_eq!(Into::<usize>::into (Myenum4::X), 0);
308 assert_eq!(Some (Myenum4::X), Myenum4::from_usize (0));
309 assert_eq!(None, Myenum4::from_usize (1));
310 assert_eq!(Some (0), Myenum4::X.to_usize());
311 assert_eq!(enum_iterator::first::<Myenum4>().unwrap(), Myenum4::X);
312 assert_eq!(enum_iterator::last::<Myenum4>().unwrap(), Myenum4::X);
313 let mut i = enum_iterator::all::<Myenum4>();
314 assert_eq!(i.next(), Some (Myenum4::X));
315 assert_eq!(i.next(), None);
316 assert_eq!(enum_iterator::next (&Myenum4::X), None);
317 assert_eq!(enum_iterator::previous (&Myenum4::X), None);
318
319 enum_unitary!{
321 #[derive(Debug, PartialEq)]
322 enum Myenum5 { }
323 }
324 assert_eq!(enum_iterator::cardinality::<Myenum5>(), 0);
325 assert_eq!(None, Myenum5::from_usize (0));
326 assert_eq!(enum_iterator::first::<Myenum5>(), None);
327 assert_eq!(enum_iterator::last::<Myenum5>(), None);
328 let mut i = enum_iterator::all::<Myenum5>();
329 assert_eq!(i.next(), None);
330
331 enum_unitary!{
333 #[derive(Debug, PartialEq)]
334 pub enum Myenum6 { }
335 }
336 assert_eq!(enum_iterator::cardinality::<Myenum6>(), 0);
337 assert_eq!(None, Myenum6::from_usize (0));
338 assert_eq!(enum_iterator::first::<Myenum6>(), None);
339 assert_eq!(enum_iterator::last::<Myenum6>(), None);
340 let mut i = enum_iterator::all::<Myenum6>();
341 assert_eq!(i.next(), None);
342 }
343}