What I want to solve is
lookup!(cfg, val => [A, B, C, D, ... Z]);
So example:
let c: C = lookup!("blarf", 2 => [A, B, C, D, ...Z]) // Equivalent of calling C::create("blarf");
All types implement trait
trait Create {
create(cfg: ...) -> Self;
}
The macro definition would look something like:
macro_rules! lookup {
($cfg:expr, $m:expr => [ $( $a:ty ),* ]) => {
match $m {
$(
i => <$a>::create(cfg)
)*
}
}
}
But I cannot figure out how the macro would be for the match statement. Any suggestions?
P.S.
I could of course just write a function as:
let i = 2;
let cfg = ...
let c: C = match i {
0 => A::create(cfg);
1 => B::create(cfg);
2 => C::create(cfg);
...
};
Every arm of a match has to evaluate to the same type. Types can't be dependent on runtime values, modulo being erased (e.g dyn Trait
, *const ()
).
2 Likes
If you know the types ahead of time, you can move the comparison into the macro system
#![allow(dead_code, unused_variables)]
trait Create {
fn create(cfg: &'static str) -> Self;
}
struct C;
impl Create for C {
fn create(cfg: &'static str) -> Self {
todo!()
}
}
macro_rules! lookup {
($cfg:expr, $m:tt) => {
<lookup!(@internal $m)>::create($cfg)
};
(@internal 0) => {
A
};
(@internal 1) => {
B
};
(@internal 2) => {
C
}
}
fn check() {
let c: C = lookup!("blarf", 2);
}
I'm not sure if that will be helpful to what you're trying to do though
Thanks, this achieves what I want!
system
Closed
5
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.