Reputation: 2561
I'm trying to create a macro-based finite state machine, and I'm having issues figuring out how to get my repeating pattern to capture multiple lines of tokens. I've tried moving the repetition block around and changing the delimiters between lines, but that didn't seem to get me closer. I couldn't find examples of using multiple tokens in a single repeat pattern, so I'm guessing I am breaking some sort of rule there which I couldn't find...
macro_rules! build_machine {
($($state_a:tt : $activity:tt -> $state_b:tt),* $(,)*) => {
#[derive(Debug)]
enum State { $( $state_a, $state_b )* }
#[derive(Debug)]
enum Activity { $( $activity )* }
}
}
build_machine!(
Locked : TurnKey -> Unlocked,
//Stopped : Push -> Moving,
);
fn main() {
println!(
"{:?} + {:?} -> {:?}",
State::Locked,
Activity::TurnKey,
State::Unlocked,
);
// println!(
// "{:?} + {:?} -> {:?}",
// State::Stopped,
// Activity::Push,
// State::Moving,
// );
}
It works as expected like this, but adding in the commented lines gives a weird error complaining about the missing comma at the comma:
error: expected one of `(`, `,`, `=`, `{`, or `}`, found `Stopped`
--> src/main.rs:13:5
|
12 | Locked : TurnKey -> Unlocked,
| -
| |
| expected one of `(`, `,`, `=`, `{`, or `}`
| help: missing `,`
13 | Stopped : Push -> Moving,
| ^^^^^^^ unexpected token
I'm new to macros, but I think using a macro_rules
is a better fit than using a proc_macro
. However, I'm fine switching if that's not the case.
Upvotes: 0
Views: 2536
Reputation: 222168
You're missing commas in the generated code:
#[derive(Debug)]
enum State { $( $state_a, $state_b, )* }
// ^ this
#[derive(Debug)]
enum Activity { $( $activity, )* }
// ^ and this
Without those your macro is generating invalid code if the outer macro has more than one repetition.
Upvotes: 1