use core::convert::Infallible;
pub trait Enum: Sized {
const LENGTH: usize;
fn from_usize(value: usize) -> Self;
fn into_usize(self) -> usize;
}
pub trait EnumArray<V>: Enum {
type Array: Array<V>;
}
pub unsafe trait Array<V> {
const LENGTH: usize;
fn slice(&self) -> &[V];
fn slice_mut(&mut self) -> &mut [V];
}
unsafe impl<V, const N: usize> Array<V> for [V; N] {
const LENGTH: usize = N;
fn slice(&self) -> &[V] {
self
}
fn slice_mut(&mut self) -> &mut [V] {
self
}
}
impl Enum for bool {
const LENGTH: usize = 2;
#[inline]
fn from_usize(value: usize) -> Self {
match value {
0 => false,
1 => true,
_ => unreachable!(),
}
}
#[inline]
fn into_usize(self) -> usize {
usize::from(self)
}
}
impl<T> EnumArray<T> for bool {
type Array = [T; Self::LENGTH];
}
impl Enum for u8 {
const LENGTH: usize = 256;
#[inline]
fn from_usize(value: usize) -> Self {
value.try_into().unwrap()
}
#[inline]
fn into_usize(self) -> usize {
usize::from(self)
}
}
impl<T> EnumArray<T> for u8 {
type Array = [T; Self::LENGTH];
}
impl Enum for Infallible {
const LENGTH: usize = 0;
#[inline]
fn from_usize(_: usize) -> Self {
unreachable!();
}
#[inline]
fn into_usize(self) -> usize {
match self {}
}
}
impl<T> EnumArray<T> for Infallible {
type Array = [T; Self::LENGTH];
}