Concisely put into Rust code, I'm trying to generate a pattern match like this:
if let Foo::Variant(_) = value {}
// ^^^^^^^^^^^^^^^
in a macro, with both Foo (a type) and Variant (an identifier) passed to the macro as metavariables. In the real use case, I'm generating a match instead of an if let and am using multiple variants of the same enum, but if let resulted in a shorter reproducible example.
This works with simple enums:
enum Foo {
Variant,
}
macro_rules! match_enum {
(
$value:ident: <$enum:ty>::$variant:ident
) => {
if let <$enum>::$variant = $value {}
};
}
fn main() {
let foo = Foo::Variant;
match_enum!(foo: <Foo>::Variant);
}
This compiles.
However, when I make the enum variant tuple-like, it breaks (changes highlighted):
enum Foo {
Variant(usize),
// ^^^^^^^
}
macro_rules! match_enum {
(
$value:ident: <$enum:ty>::$variant:ident
) => {
if let <$enum>::$variant(_) = $value {}
// ^^^
};
}
fn main() {
let foo = Foo::Variant(0);
// ^^^
match_enum!(foo: <Foo>::Variant);
}
| if let <$enum>::$variant(_) = $value {}
| -----------------^^^ unexpected `(` after qualified path
| |
| the qualified path
...
| match_enum!(foo: <Foo>::Variant);
| --------------------------------- in this macro invocation
I have tried some variations, more or less blindly; $enum::$variant(_), <$enum::$variant>(_), <$enum::$variant>::(_) among them.
Is this possible? Am I perhaps using the wrong types of metavariables?
This question seems to be related, but it focuses on mixing unit and tuple variants, and has not been resolved.