enum_map/
internal.rs
1use core::cmp::Ordering;
8use core::convert::Infallible;
9
10pub trait Enum: Sized {
18 const LENGTH: usize;
20
21 fn from_usize(value: usize) -> Self;
23 fn into_usize(self) -> usize;
25}
26
27pub trait EnumArray<V>: Enum {
33 type Array: Array<V>;
35}
36
37pub unsafe trait Array<V> {
45 const LENGTH: usize;
48}
49
50unsafe impl<V, const N: usize> Array<V> for [V; N] {
51 const LENGTH: usize = N;
52}
53
54#[doc(hidden)]
55#[inline]
56pub fn out_of_bounds() -> ! {
57 panic!("index out of range for Enum::from_usize");
58}
59
60impl Enum for bool {
61 const LENGTH: usize = 2;
62
63 #[inline]
64 fn from_usize(value: usize) -> Self {
65 match value {
66 0 => false,
67 1 => true,
68 _ => out_of_bounds(),
69 }
70 }
71 #[inline]
72 fn into_usize(self) -> usize {
73 usize::from(self)
74 }
75}
76
77impl<T> EnumArray<T> for bool {
78 type Array = [T; Self::LENGTH];
79}
80
81impl Enum for () {
82 const LENGTH: usize = 1;
83
84 #[inline]
85 fn from_usize(value: usize) -> Self {
86 match value {
87 0 => (),
88 _ => out_of_bounds(),
89 }
90 }
91 #[inline]
92 fn into_usize(self) -> usize {
93 0
94 }
95}
96
97impl<T> EnumArray<T> for () {
98 type Array = [T; Self::LENGTH];
99}
100
101impl Enum for u8 {
102 const LENGTH: usize = 256;
103
104 #[inline]
105 fn from_usize(value: usize) -> Self {
106 value.try_into().unwrap_or_else(|_| out_of_bounds())
107 }
108 #[inline]
109 fn into_usize(self) -> usize {
110 usize::from(self)
111 }
112}
113
114impl<T> EnumArray<T> for u8 {
115 type Array = [T; Self::LENGTH];
116}
117
118impl Enum for Infallible {
119 const LENGTH: usize = 0;
120
121 #[inline]
122 fn from_usize(_: usize) -> Self {
123 out_of_bounds();
124 }
125 #[inline]
126 fn into_usize(self) -> usize {
127 match self {}
128 }
129}
130
131impl<T> EnumArray<T> for Infallible {
132 type Array = [T; Self::LENGTH];
133}
134
135impl Enum for Ordering {
136 const LENGTH: usize = 3;
137
138 #[inline]
139 fn from_usize(value: usize) -> Self {
140 match value {
141 0 => Ordering::Less,
142 1 => Ordering::Equal,
143 2 => Ordering::Greater,
144 _ => out_of_bounds(),
145 }
146 }
147 #[inline]
148 fn into_usize(self) -> usize {
149 match self {
150 Ordering::Less => 0,
151 Ordering::Equal => 1,
152 Ordering::Greater => 2,
153 }
154 }
155}
156
157impl<T> EnumArray<T> for Ordering {
158 type Array = [T; Self::LENGTH];
159}