I need a type which can have a bunch of variants with no data (C like enums) which I can match on. It is a closed set. Enums would do just fine and were designed for this, but
there are hundreds of variants and lots of methods. Eg:
enum Type {
Variant0,
//...
Variant150,
}
fn get_some_info(&self) -> i32 {
// match with 151 cases.
}
fn get_some_other_info(&self) -> i32 {
// match with 151 cases again.
}
Now add like 10 methods and it becomes ugly and a monster file. With the enum approach, I also can't have variants have their own non polymorphic methods.
I figured I could use trait objects here. Of course I won't box them as there's no data. I can use a static lifetime. So I need to store
the variants as static data.
Eg:
trait Type {
//methods
}
struct Variant0;
impl Type for Variant0 {/*methods*/}
// ...
struct Variant150;
impl Type for Variant150 {/*methods*/}
static VARIANT0: &Variant0 = &Variant0;
// ...
static VARIANT150: &Variant150 = &Variant150;
Cool. Now I just use &'static Type
in the places I could have used enum as Type
and pass it the static variables. But then, how do I match?
As far as I'm aware of, static variables are stored in the executable and their memory addresses won't change. So I guess I could match on raw pointer values.
fn do_something(type: &'static Type) {
match type as *const Type {
VARIANT0 as *const Type => // boom error.
}
}
I tried other ways like:
fn do_something(type: &'static Type) {
const VARIANT0_addr: usize = VARIANT0 as *const Variant0 as usize;
match t as *const Trait as usize { // error here..
VARIANT0_addr => println!("HELLO"),
}
}
But this gives a more confusing error saying pointer to traits can't be casted to usize. Why? I thought a pointer is a pointer.
Soo how do I do this? One option is using polymorphism and implement these matches as methods on the trait. I don't like this because
I am serializing and deserializing these variants as their numeric values. While deserializing, I will need to use a match for matching on the number anyway. So I would like to use match for serialization part as well and keep them in a single place rather than scattering the numeric values everywhere.