Reputation: 2039
I am working on Rust macros to generate a static array of structures that describe FFI callbacks. What I currently have is...
// some trivial callback functions
extern "C" fn my_fun_1(argc: u32, argv: *const i32) -> i32 { 1 }
extern "C" fn my_fun_2(argc: u32, argv: *const i32) -> i32 { 2 }
// create static array of ErlNifFunc describing above callbacks
nif_init!(b"my_module\0",
nif!(b"my_fun_1\0", 3, my_fun_1),
nif!(b"my_fun_2\0", 5, my_fun_2));
(whole thing is here)
This works because I only need to provide one expansion of the information provided to the nif!
macro. But now, in addition to generating an array of structs, I want to work towards generating wrapper functions for the provided functions. So, I can't invoke nif!
right away because I now need to do more than one expansion pass on the underlying parameters. I effectively need to move the nif!
invocations inside nif_init!
, and this is where I drown. I think the top level nif_init!
needs to look like this...
nif_init!(b"my_module\0",
(b"my_fun_1\0", 3, my_fun_1),
(b"my_fun_2\0", 5, my_fun_2));
... with the inner parenthesised parameters getting passed on to sub-macros, but I just cannot make it go. The full non-working thing is here. To clarify, this version just tries to do the macro invocation internally. I'm not trying to generate any wrapper functions yet.
Upvotes: 2
Views: 1089
Reputation: 430673
For this case, you can't use parentheses as grouping, you need to use them as part of your macro pattern. I'd avoid using parens to avoid this confusion.
Here, I changed your macro a bit to accept zero-or-more sets of {}
. You can macro-iterate over each of them and call your inner macro:
macro_rules! nif_inner {
($name:expr, $args:expr, $meth:expr) => ()
}
macro_rules! nif_init {
($module:expr, $({ $name:expr, $args:expr, $meth:expr }),*) => (
$(nif_inner!(name, $args, $meth);)*
)
}
nif_init!(
"hello",
{ "name1", 1, true },
{ "name2", 2, false }
);
fn main() {}
Upvotes: 4