There's one other thing you might want to consider. You have an enum
with variant names matching existing empty/unit struct
s. You can put those struct
s into the enum
variants at zero cost:
pub enum CorrelationMethod {
Method1(Method1),
Method2(Method2),
Method3(Method3),
}
It doesn't particularly impact what you're exploring, but if you're looking to export this for use elsewhere or repeat it many times for different calculations it could really simplify your access pathways.
- Gives you access to the underlying methods from just the single
CorrelationMethod
- Which also allows you to ignore the individual
MethodN
s you have, and leave them private.
- This also ensures match arms are in functions implemented on the top-level
enum
,
- Rather than in separate/independent functions.
// New methods allow for creation without having Method1/Method2/Method3/etc.
impl CorrelationMethod {
pub fn new_method1() -> Self { Self::Method1(Method1{}) }
pub fn new_method2() -> Self { Self::Method2(Method2{}) }
pub fn new_method3() -> Self { Self::Method3(Method3{}) }
}
impl Correlation for Method {
fn compute(&self, a: i32, b: i32) -> i32 {
match &self {
Self::Method1(method) => method.compute(a, b),
Self::Method2(method) => method.compute(a, b),
Self::Method3(method) => method.compute(a, b),
}
}
}
Which leads me to a question I've had - is there any way to condense that final match statement knowing that EVERY variant implements the same trait? I presume it's a question of how to tell the compiler that future variants which could break the pattern can't/won't be added.
At the very least, this reduces some repeated bits:
match self {
Self::Method1(m) | Self::Method2(m) | Self::Method3(m) => m.compute(a, b)
}