1use core::cmp::Ordering;
8use core::convert::Infallible;
9
10pub trait Enum: Sized {
18 type Array<V>: Array;
26
27 fn from_usize(value: usize) -> Self;
29 fn into_usize(self) -> usize;
31}
32
33pub unsafe trait Array {
41 const LENGTH: usize;
44}
45
46unsafe impl<V, const N: usize> Array for [V; N] {
47 const LENGTH: usize = N;
48}
49
50#[doc(hidden)]
51#[inline]
52pub fn out_of_bounds() -> ! {
53 panic!("index out of range for Enum::from_usize");
54}
55
56impl Enum for bool {
57 type Array<V> = [V; 2];
58
59 #[inline]
60 fn from_usize(value: usize) -> Self {
61 match value {
62 0 => false,
63 1 => true,
64 _ => out_of_bounds(),
65 }
66 }
67 #[inline]
68 fn into_usize(self) -> usize {
69 usize::from(self)
70 }
71}
72
73impl Enum for () {
74 type Array<V> = [V; 1];
75
76 #[inline]
77 fn from_usize(value: usize) -> Self {
78 match value {
79 0 => (),
80 _ => out_of_bounds(),
81 }
82 }
83 #[inline]
84 fn into_usize(self) -> usize {
85 0
86 }
87}
88
89impl Enum for u8 {
90 type Array<V> = [V; 256];
91
92 #[inline]
93 fn from_usize(value: usize) -> Self {
94 value.try_into().unwrap_or_else(|_| out_of_bounds())
95 }
96 #[inline]
97 fn into_usize(self) -> usize {
98 usize::from(self)
99 }
100}
101
102impl Enum for Infallible {
103 type Array<V> = [V; 0];
104
105 #[inline]
106 fn from_usize(_: usize) -> Self {
107 out_of_bounds();
108 }
109 #[inline]
110 fn into_usize(self) -> usize {
111 match self {}
112 }
113}
114
115impl Enum for Ordering {
116 type Array<V> = [V; 3];
117
118 #[inline]
119 fn from_usize(value: usize) -> Self {
120 match value {
121 0 => Ordering::Less,
122 1 => Ordering::Equal,
123 2 => Ordering::Greater,
124 _ => out_of_bounds(),
125 }
126 }
127 #[inline]
128 fn into_usize(self) -> usize {
129 match self {
130 Ordering::Less => 0,
131 Ordering::Equal => 1,
132 Ordering::Greater => 2,
133 }
134 }
135}