In a recent project i've relied somewhat heavily on generics. Now I want to be able to configure the runtime by reading json files. However, I can't quite settle on a clean way to parse json files and dynamically dispatching the data structures.
Here is a quick - sorry for the very foolish - example: Playground
Now my questions are:
What are the idiomatic ways in general to model the "interface" between statically dispatched types and runtime polymorphism? Ideally I'd like the parsing layer to be quite thin.
Finally, I found it hard to express these problems (both here and whilst searching the webs) and so I didn't find any good reading sources on this, even though I'm very happy with Rust literature in general.
One way would be to implement a trait (in your example the Algorithm and SearchSpace traits) on the corresponding dyn boxes (Box<dyn Algorithm> and Box<dyn SearchSpace> respectively in your example) and then pass in these dyn boxes as the generic arguments. If you will only ever use it dynamically, I'd switch entirely to this box-based runtime polymorphism system. The downside here is that it will be slightly slower due to dynamic dispatch overhead, but it's likely fine unless function call overhead is a large part of your algorithm's CPU time. It's also a bit messy.
The main alterantive is to have a copy of your generic struct's member functions instantiated somewhere in the binary for each possible combination of types, however as far as I know there's no way to do this automatically. You'd need something like a match of each possible combination that trampolines to the appropriatea generic, e.g.
match types{
(Algorithms::AlgorithmA, Spaes::SpaceB) => MyStruct<AlgorithmA, SpaceB>::do_something(),
//… and so on for each combination that you support
}
A macro might help generate this type of match expression.