Hi!
I'm having the following struggle with Rust:
Normally in C++ I would do something like this:
enum MyEnum {
A,
B,
NumEnums
};
int main()
{
int my_array[NumEnums];
my_array[A] = 5;
}
In Rust we can achieve very similar results with plain enums and repr:
#[repr(usize)]
enum MyEnum {
A,
B,
NumEnums
}
fn main() {
let my_array = [0; MyEnum::NumEnums as usize];
my_array[MyEnum::A as usize] = 5;
}
So far, so good. The problem is that I find constantly typing as usize to be incredibly distracting for readability (not to mention that it's unnecessary considering Rust has all the information needed to automatically cast and inform me at build time if the cast to usize fails or would cause an issue).
But I'm not here to question the language semantics. I need to get stuff done.
In Rust enums are much more than enums are in C++; so perhaps "enums", are the wrong approach.
I tried a different approach using constants + modules and indeed it works as I want:
#![allow(non_snake_case, non_upper_case_globals)]
mod MyEnum {
const A : usize = 0;
const B : usize = 1;
#![allow(non_snake_case, non_upper_case_globals)]
const NumEnums : usize = 2;
}
fn main() {
let my_array = [0; MyEnum::NumEnums];
my_array[MyEnum::A] = 5;
}
Yay! Success. The only thing I lost is type safety though (i.e. a type that always validates the values are in range [0; NumEnums], though NumEnums is out of bounds).
But the biggest issue that I need to explicitly set the number.
If later add a new value "C"; I could do the following mistakes:
- Set "C" a value other than 2 (typing bug).
- Forget to update NumEnums to 3.
Also adding more values in between existing ones means updating all subquent declarations (where I could accidentally introduce a typing bug).
These are all preventable bugs because all I care is that their values are automaically generated, starting from 0, monotonically increasing, and without cluttering readability.
I tried to use a macro, but rust macros appear to be very bad at counting? (or I'm just bad at making macros, which I am).
I could write a procedural macro; but at this point I'm questioning why is it so hard to get something this simple.
- Are there crates that handle this problem? (I couldn't find any, but it's hard to google for this problem)
- Do you think there are better approaches? Better solutions?
Cheers