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.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.