Hi all,
I am struggling with generics in a project of mine, and I would like some help setting things up cleanly.
It is a binary using clap, and I want the user to be able to access the functionality of an ever-growing list of modules whose behavior depends on user input. I am currently using the lazy-static
crate to achieve this in a static context. For example:
pub mod m1;
...
pub mod mN;
lazy_static! {
pub static ref MODULES:
HashMap<&'static str, fn(Settings) -> dyn CommonTrait> = {
let mut map = HashMap::new();
map.insert(m1::NAME, m1::Struct::initialize);
...
map.insert(mN:NAME, mN::Struct::initialize);
map
}
}
...allowing a command like binary --target m1_name --settings 258292
to be parsed by matching m1_name
against the keys in the map, and passing the settings 258292
into the initialization function it maps to.
This is my first question -- is this the best way to map user input to specific module behavior? Keep in mind that it is very important to minimize the development effort to add an m(N+1)
module in my case, which is why these aren't just hard coded into some match statement.
Now, the real reason I am asking for help is because I want to add another layer of complexity/freedom. Namely, making another trait (which all of the Struct
s referenced above implement) generic over an integer:
AnotherCommonTrait<const N: usize>
Here, all Struct
s could have multiple implementations for different arbitrary N
values. This is important because I am using the nalgebra
crate, and making Struct
s generic over integers actually makes a lot of sense in my use case. However, this kind of makes the complexity of the previous approach blow up, where I would need something like the following to make it work out:
lazy_static! {
pub static ref MODULES:
HashMap<&'static str,
HashMap<usize, fn(Settings) -> dyn CommonTrait>> = {
...
/// { X => Y} just being another map:
map.insert(m1::NAME,
{ 1 => <m1::Struct as AnotherCommonTrait<1>>::initialize,
...
}
);
...
}
Which is pretty awful, and I don't even know if it would work. I feel like I am suffering some serious tunnel vision here, so I would welcome any ideas.
Thank you!