Reputation: 1430
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
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
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();
}
Note that I had to slightly change the code you gave because it wasn't compiling.
Upvotes: 2
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