Happy Easter everyone,
in my code I have two entities (an electric motor winding and a lamination, to be precise). Both winding and lamination may have multiple variants, which could be represented either by an enum variant or by a "Winding" / "Lamination" trait and corresponding implementations for specific structs. I prefer the latter solution to allow other users to create their own variants.
I now have the following issue: The implementation of a trait function depends on the specific winding / lamination combination. Therefore I created a generic new wrapper struct which holds both winding and lamination:
struct Component<W: Winding, L: Lamination> {
winding: W,
lamination: L,
}
I'd now like to implement the trait function for Component
with different implementations depending on the types W
and L
. As far as I understand, this would be a use case for specialization, however I'd like to have a solution in stable Rust.
I had the idea to use the trait function as a wrapper around other, specific function implementations (with unique names). To achieve this, I created the following MWE:
use paste::paste;
macro_rules! call_specialized_function {
($arg1: ty, $arg2: ty) => {
paste! {
// Call function
[<add_ $arg1 _to_ $arg2>]();
}
}
}
fn add_i32_to_i32() -> () {
println!("Added i32 to i32!")
}
fn add_i32_to_f64() -> () {
println!("Added i32 to f64!")
}
fn main() {
caller(1i32);
caller(1.0);
}
fn caller<T,S>(arg1: T, arg2: S) -> () {
call_specialized_function!(T, S);
}
Playground: Rust Playground
However, this doesn't work because T
and S
are parsed as literals (i.e. the compiler complains that no function add_T_to_S
is defined). If I use call_specialized_function!(i32, f64);
instead, the macro works as intended.
As far as I understand, my goal can't be achieved because the macro doesn't know about the types of T
and S
during expansion. Is there some other way to achieve my goal?