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