Margareth Reena
Margareth Reena

Reputation: 1430

How to define different function names with a macro?

I've been tyring to define a different function for eacu unsigned type in Rust, and of course they have to have different names because Rust can't pick the right one by signature. So I'm trying to give them different names but I was unable to do so:

macro_rules! define_my_function {
    ($t:ty, $f_name:ident) => {
        pub fn concat_idents!(my_function_, $ty)()(
            stream: &mut T
        ) -> Result<$ty, ParseError> {
            todo!()
        }
    }
}

define_my_function!(u8, name_for_u8);


   Compiling playground v0.0.1 (/playground)
error: expected one of `(` or `<`, found `!`
  --> src/lib.rs:3:29
   |
3  |         pub fn concat_idents!(my_function_, $ty)()(
   |                             ^ expected one of `(` or `<`
...
11 | define_my_function!(u8, name_for_u8);
   | ------------------------------------- in this macro invocation

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9ccea3ddcc75bb2cfab14c52df7bc24f

It looks like this is impossible in Rust. What can I do then? Also I don't want to use concat_idents as it's nightly only

Upvotes: 1

Views: 2878

Answers (2)

Filipe Rodrigues
Filipe Rodrigues

Reputation: 2177

You can use the paste crate, that internally uses a procedural macro to create new identifiers:

macro_rules! define_my_function {
    ($t:ty) => {
        ::paste::paste! {
            pub fn [<my_function_ $t>]() {
                println!(stringify!($t));
            }
        }
    }
}

define_my_function!(u8);
define_my_function!(u16);

fn main() {
    my_function_u8();
    my_function_u16();
}

Playground

Note that I had to slightly change the code you gave because it wasn't compiling.

Upvotes: 2

Coder-256
Coder-256

Reputation: 5618

From the documentation for std::concat_idents:

Also, as a general rule, macros are only allowed in item, statement or expression position. That means while you may use this macro for referring to existing variables, functions or modules etc, you cannot define a new one with it.

Unfortunately, it seems that at the time this is possible using a procedural macro, or by manually copy-pasting for each numeric type.

Upvotes: 0

Related Questions