Imagine a struct...
struct Pair {
letter: Letter,
number: Number,
}
enum Letter {A, B, C}
enum Number {One, Two, Three}
The total number of combinations in this struct would be 3 x 3 = 9, however, I want to make only some of them possible. Say, I allow all combinations to exist, but {C, Three} cannot exist, for whatever reason.
How can the type system in Rust help me achieve this such that if I have a constructor for Pair...
impl Pair {
fn new(letter : Letter, number : Number) -> Pair {
...
}
}
and then later in my main function I do... Pair::new(Letter::C, Number::Three);
the compiler raises a compile-time error instead of panicking during runtime?
One possibility is to use const eval to make sure invalid combinations don't compile:
impl Pair {
const fn new(letter: Letter, number: Number) -> Pair {
assert!(!matches!((letter, number), (Letter::C, Number::Three)));
...
}
}
But marking the function as const
does not guarantee it will be evaluated at compile time, only makes that possible. To guarantee that, you can use a macro:
macro_rules! new_Pair {
($letter:expr, $number:expr $(,)?) => {{
const V: Pair = Pair::new($letter, $number);
V
}};
}