Defining Functions in Macros

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

I have recently used paste - Rust for something similar and your usecase is in the examples so it should work pretty easily.

1 Like

The current test case fails to be compiled.

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

Can I not use a third-party library?

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

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.