zoey
December 5, 2024, 11:34am
1
macro_rules! GeneratingFunctions{
($name:ident) => {
fn read_$name() { // Function names are concatenated here, how to do?
}
};
}
GeneratingFunctions!(test);
fn main() {
read_test();
}
| fn read_$name() { // Function names are concatenated here, how to do?
............ | ^ help: add a parameter list
luca3s
December 5, 2024, 11:50am
2
I have recently used paste - Rust for something similar and your usecase is in the examples so it should work pretty easily.
1 Like
zoey
December 5, 2024, 12:03pm
3
The current test case fails to be compiled.
luca3s
December 5, 2024, 12:16pm
4
It works like this.
use paste;
macro_rules! GeneratingFunctions{
($name:ident) => {
paste::paste! (
fn [<read_ $name>]() { // Function names are concatenated here, how to do?
}
);
};
}
GeneratingFunctions!(test);
fn main() {
read_test();
}
2 Likes
zoey
December 5, 2024, 12:54pm
5
Can I not use a third-party library?
luca3s
December 5, 2024, 1:01pm
6
If you want to mix the name together i don't know any other way. You could of course always do it like this:
macro_rules! GeneratingFunctions{
($name:ident) => {
fn $name() { // Function names are concatenated here, how to do?
}
};
}
GeneratingFunctions!(read_test);
fn main() {
read_test();
}
Making new identifiers can only be done with proc macros-- Declarative macros can only shuffle around identifiers that already exist either at the callsite or within the macro definition itself. If you want to avoid third-party libraries, you'll have to write this using the proc macro system.
A pattern I use a lot is to have the macro generate a module definition:
macro_rules! GeneratingFunctions{
($viz:vis $name:ident) => {
$viz mod $name {
pub fn read() { ... }
}
};
}
GeneratingFunctions!(test);
fn main() {
test::read();
}
2 Likes
zoey
December 5, 2024, 1:16pm
8
if proc macros, how to do ?
That's not part of Rust that I'm particularly familiar with, but there's a chapter in the book about how to write them and one in the reference with all the details.