Hello,
I created a macro based on the suggestion from @h2co3 in this thread: https://users.rust-lang.org/t/dyn-dispatch-on-multiple-types
My code is here: GitHub - luketpeterson/double_dyn: Macro for implementing functions with multiple dynamic argument dispatch
@h2co3's suggested approach compiles to very reasonable code, but it had the drawback of requiring a dense implementation matrix. In other words, to support a new A
type, it was necessary to add a new function to the "Level 1 Trait" and therefore touch every single implementation. To add a new B
type, it's necessary to implement the corresponding function for every A
type. So the number of functions grows as n^2 where n is the number of supported types.
This macro still ends up generating all those functions, but at least the clutter is hidden away.
An example macro invocation looks like this:
double_dyn!{
type A: MyTraitA;
type B: MyTraitB: std::fmt::Display;
fn multiply(a: &dyn MyTraitA, b: &dyn MyTraitB) -> Box<dyn MyTraitB>;
impl for <i32, String>
{
fn multiply(a: &i32, b: &String) -> Box<dyn MyTraitB> {
let multiplied_val = *a * b.parse::<i32>().unwrap();
Box::new(multiplied_val.to_string())
}
}
impl for <[i8, i16, i32, i64, i128], [f32, f64]>
{
fn multiply(a: &#A, b: &#B) -> Box<dyn MyTraitB> {
Box::new((*a as #B) * *b)
}
}
}
let val = multiply(&2, &7.5);
So: I'm looking for suggestions on:
- Ways to make the syntax "Rustier".
- Whether this is useful to you, or changes I could make so it would be more useful
- If there might be a way to spread the implementation across multiple macro invocations. i.e. to add additional impls to functions defined in another block. i.e. does anyone know a robust work-around for Crate local state for procedural macros? · Issue #44034 · rust-lang/rust · GitHub ?
Any thoughts are appreciated.
Thank you.