I want to accept struct members in a declarative macro as a simple way of generating enums with common members (I think I have to do it this way because I want to deserialise from a pre-determined JSON format with serde), but it doesn't work:
What I think should work:
macro_rules! test {
($field_1:tt, $field_2:tt) => {
#[derive(Debug)]
struct Test {
first: String,
$field_1,
$field_2,
}
};
}
test!(a: i32, b: i32);
The error:
Compiling playground v0.0.1 (/playground)
error: no rules expected the token `:`
--> src/lib.rs:12:8
|
1 | macro_rules! test {
| ----------------- when calling this macro
...
12 | test!(a: i32, b: i32);
| ^ no rules expected this token in macro call
|
note: while trying to match `,`
--> src/lib.rs:2:17
|
2 | ($field_1:tt, $field_2:tt) => {
| ^
error: could not compile `playground` (lib) due to previous error
Is there any way to do this, or would I have to resort to a proc macro?
A TokenTree
(:tt
) is a "single token or a delimited sequence of token trees" You're missing delimiters / aren't matching enough of the token trees (there are three per field definition).
To make this work, you can just match all three token trees that make up the field definition:
macro_rules! test {
($id1:ident : $type1:ty, $id2:ident: $type2:ty) => {
#[derive(Debug)]
struct Test {
first: String,
$id1: $type1,
$id2: $type2,
}
};
}
Or for an arbitrary number of field definitions:
macro_rules! test {
($($id:ident : $type:ty),* $(,)?) => {
#[derive(Debug)]
struct Test {
first: String,
$($id : $type),*
}
};
}