I have an enum encapsulating a set of limited types that I would like implementors of a trait Op
to accept as a possible method argument. The enum wrapping should be done away with once Op
gets it's contents. I implement the trait Op
for a bunch of structs, then at runtime, I want to dynamically determine which objects get which argument of the possible types using an enum. This sounds confusing so here's some code
enum AllTypes {
U32s(Vec<u32>),
U8s(Vec<u8>),
Dates(Vec<Date>),
...
}
trait Op<T> {
fn op(&self, _: T) {}
}
// at runtime something like this might happen
if arglist == ("u32", "u8") {
let op: &dyn Op<(u32, u8)> = ...;
args = Arg::U32ThenU8(op);
} else { ... }
// some time later with alltypes variable defined in scope
match args {
// OurMap basically maps it's closure's output to the ops input using generics
Arg::U32ThenU8(op) => OurMap(op, move |alltypes| (alltypes.get_u32s()[0], alltypes.get_u8s()[0])),
... // all the other possible permutations of Arg variants.. this is the daunting part
}
I'm pretty sure this will work, ignoring the unboxed pseducode closure above. The point is, I can map Arg type to an implementors of Op<T>
. The daunting part is the Arg
enum. I have 12 possible variants for the AllTypes
enum. And because I don't see any other way to do this but to define a maximum number of types that can be mixed together (arity) THEN write each possible permutation of those types mixed together, I am stuck simply because hand writing this is extremely tedious.
enum Arg {
U32(&dyn Op<u32>),
U8(&dyn Op<u8>),
Usize(...)
Date(...)
U32ThenU8(...)
U8ThenU32(...)
U32ThenUsize(...)
... // not even close to done
}
Not to mention the match statements for Arg.. I know in rust there are macros like println! that are somewhat variadic. I can do this with C++ variadic templates. How do I do this kind of thing in Rust? Macros?
The code above is completely contrived and only for demonstration purposes. The program is basically an interpreter.