Nice and efficient idiom for Array indexed by c-like enum?

Hi all,

I’m wondering how I could nicely and efficiently implement a simple array mapping from a simple finite enum such as

enum Status { Good, Bad, Ugly }

to some other type. I could do this by implementing Index with a big match, but that sounds clumsy and likely to not compile to a simple index. I could implement Index with an as usize, but then I wonder if it will end up doing bounds checks. Neither sounds pretty.

Any suggestions for an idiomatic way to express this?


If you want map to you can do simple thing:

enum Status {
    Good = 0, Bad = 1, Ugly = 2

and then you can write:

let a = Status::Bad;
let b = a as u8;

and you can use any integer type instead of u8.

Ada language allows that kind of indexing in a perfectly safe and efficient way (the type of the array is indexable only with the correct type of index), with short code and syntactic convenience. Rust (and D language) are still sorely lacking on this… I’d like a RFC on this.

In Rust I guess you can use an unsafe indexing function that avoids the bounds checks.


Unless it got reverted, the compiler should be telling LLVM the maximum value of the enum so bounds checks can be elided.

That’s encouraging, @DroidLogician! For those who might be curious (and any additional advice), I’ve implemented an array mapping an enum below. The only ugliness remaining is that I have to hard-code the size of the array, since I can’t access “Status::Dirty as usize” as a constant.

#[derive(PartialEq, Eq, Hash, Copy, Clone)]
pub enum Status {

pub struct StatusMap<T>( [T;9] );

impl<T> StatusMap<T> {
    fn new<F>(v: F) -> StatusMap<T>
        where F: Fn() -> T
        StatusMap( [v(),v(),v(),v(),v(),v(),v(),v(),v()] )

impl<T> std::ops::Index<Status> for StatusMap<T>  {
    type Output = T;
    fn index(&self, s: Status) -> &T {
        &self.0[s as usize]

Thanks again for the helpful advice!

1 Like