I want to implement macro that will generate struct for me, but got an error on compile:
error: `$prop_type:expr` may be followed by `#`, which is not allowed for `expr` fragments
--> src/main.rs:4:11
|
4 | $(#[$outer:meta])*
| ^ not allowed after `expr` fragments
|
= note: allowed there are: `=>`, `,` or `;`
error: `$prop_type:expr` may be followed by `$vis:vis`, which is not allowed for `expr` fragments
--> src/main.rs:5:9
|
5 | $vis:vis struct $PacketStruct:ident {
| ^^^^^^^^ not allowed after `expr` fragments
|
= note: allowed there are: `=>`, `,` or `;`
error: could not compile `playground` due to 2 previous errors
The difference is that the first one only includes ";" separators and the second one requires a semicolon after the last item of the repetition too, which matches how you intended to use it.
There's another problem after fixing that one, but I know less about it:
error: local ambiguity when calling macro `packet`: multiple parsing options: built-in NTs ident ('prop_name') or vis ('vis').
--> src/main.rs:26:9
|
26 | pub struct Outcome {
| ^^^
error: local ambiguity when calling macro `packet`: multiple parsing options: built-in NTs ident ('prop_name') or 1 other option.
--> src/main.rs:25:13
|
25 | opcode 10;
| ^^^^^^
error: could not compile `playground` due to previous error
It's the exact same ambiguity, just on the next level.
The problem here is that both your $(opcode $opcode_value:expr;)? and $($prop_name:ident: $prop_type:ty;)* may accept the line.
In that case recursion may be appropriate (since it would only be one-level): write two rules, one with opcode, one without opcode, and both would call another macro (or maybe even the same one).
Similarly to how vec!handled comma before ? was added to the macro system.