Hi everyone,
I have an application in which I would like to take pairs of different enum
types as inputs and map different pairs of their variants onto certain actions. For example, consider the following code (playground link):
#[allow(dead_code)]
enum Enum1 {
Var1,
Var2,
Var3,
}
#[allow(dead_code)]
enum Enum2 {
Var1,
Var2,
}
fn main() {
let e1 = Enum1::Var1;
let e2 = Enum2::Var2;
match (e1, e2) {
(Enum1::Var1, Enum2::Var1) => println!("1, 1"),
(Enum1::Var2, Enum2::Var2) => println!("2, 2"),
(Enum1::Var3, Enum2::Var1) => println!("3, 1"),
_ => panic!("Invalid pair of variants")
}
}
In main
, the match
statement is effectively creating a function that maps a tuple of a variant of Enum1
and a variant of Enum2
onto a specific side effect. Importantly, note that this function is not exhaustive over all pairs of variants (at least, it is not semantically valid). For example, the code above will panic because the tuple (Enum1::Var1, Enum2::Var2)
is matched by the _
pattern.
The problem with this construct is that it can be very easy to forget to add additional patterns to the match
statement as new variants are added to either Enum because the compiler still sees an exhaustive match due to the _
pattern; one must always remember to update the match statement everywhere this construct is used to accommodate the new variants.
Is there a way to solve this problem using Enums? Or would it be better to take a different approach?
To ultimately solve my problem, I will need
- to compare the values of two different types and decide what to do on a subset of the range of all possible input value pairs
- fail to compile if I have not somehow accounted for a newly-introduced value
Thanks for the help everyone!