While I landed in this forum quite a number of times when googling, this is my first post. So: Hello forum!
As part of a larger application I implemented a trait with several implementations (currently 2, expected to be 50+). Each implementation represents a certain strategy on how to proceed with the application. Users can choose at runtime which strategy to use, so hardcoding isn't an option. This is what I have so far:
impl dyn Strategy {
pub fn allocate_strategy(name: &str) -> Result<Box<dyn Strategy>, String> {
match name {
"Follow" => Ok(Box::new(Follow {})),
"Moving" => Ok(Box::new(Moving {})),
_ => Err(format!("No strategy for '{}' found", name)),
}
}
pub fn get_parameter_set(name: &str) -> Result<Vec<String>, String> {
match name {
"Follow" => Ok(Follow::get_parameter_set()),
"Moving" => Ok(Moving::get_parameter_set()),
_ => Err(format!("No strategy for '{}' found", name)),
}
}
}
pub trait Strategy {
fn recommendation(&self) -> Recommendation;
}
Follow
and Moving
are implementations of trait Strategy
. All this compiles and works fine.
What's itching me, of course, is that duplicate matching code in allocate_strategy()
and get_parameter_set()
. String name
comes from the GUI and I have to re-implement the match for every function not being a method (having self
as first parameter), just because I can't address the particular implementation somehow.
This is how it could look like, but is missing a few bits:
impl dyn Strategy {
fn find_strategy(name: &str) -> Result<?????, String> {
match name {
"Follow" => Ok(Follow),
"Moving" => Ok(Moving),
_ => Err(format!("No strategy for '{}' found", name)),
}
}
pub fn allocate_strategy(name: &str) -> Result<Box<dyn Strategy>, String> {
let strategy = Strategy::find_strategy(name)?;
Ok(Box::new(strategy {}))
}
[...]
Any ideas on how to solve this, how to de-duplicate the match?