Currently, to the best of my knowledge, it's impossible to create a macro which works exactly as you wish. It's only kind of possible. I'll explain:
- First, there is no way to count with macros, so you can't do the "repeat this n-times" on your own. This is the reason why you can't generate the strings
"test 1"
, "test 2"
and so on. It's just not possible. You can, however, create an array of structs with only "test"
as string by using the standard array initializer [val; n]
.
- Second, in order to use the array initializer, the type inside the array has to be
Copy
. But in your case that's not a big problem, since your struct can just derive it.
So let's see, what we can do (playground):
#[derive(Clone, Copy, PartialEq, Debug)]
struct Foo<'a> {
info: &'a str
}
macro_rules! make_foo {
($info:expr; $num:expr) => {
[Foo { info: $info }; $num]
}
}
First, we need to derive a few traits for your struct:
Copy
, see above
Clone
is required by Copy
PartialEq
and Debug
are required by assert_eq!()
I think the macro itself is fairly easy to understand: it's just using the array initializer internally.
But how to get exactly the behavior asked in the question?
Don't use a macro and don't use fixed size arrays. A normal function and Vec<T>
is probably fine. You could, of course, also write a compiler plugin, but those are unstable right now and it's probably not worth the hassle anyway.