To do this kind of thing, you need what's known as a tt
-muncher macro: It builds all of the text for the enum
body first, and then wraps it in the enum as the final step. A good reference for this kind of advanced macro programming is The Little Book of Rust Macros.
macro_rules! inner {
( $name:ident {$($body:tt)*} ($variant:ident) $($tail:tt)* ) => {
inner!{
$name // Enum name
{
$($body)* // Previously-built variants
$variant, // What this variant should look like
}
$($tail)* // Unprocessed variants
}
};
// When there are no more variants, emit the enum definition
( $name:ident {$($body:tt)*} ) => {
enum $name { $($body)* }
};
}
macro_rules! outer {
( $($variants:ident),* ) => {
inner!{ Test {} $(($variants))* }
}
}
(Playground)