I want my macro to accept a function call and match all arguments but if an argument it's a closure I want to handle it differently. As I'm new to Rust macros I'm not even sure of its limitations.
Some examples of what it should accept:
// one arg
my_macro!(test_fn(|a, b| {}));
// last arg
my_macro!(test_fn(42, |a, b| {}));
// middle arg
my_macro!(test_fn(42, |a, b| {}, "foo"));
In the closure argument case I need to access the inputs of the closure, capture variables and output a new closure.
So after researching a bit, I came up with this kind of approach:
macro_rules! map_if_closure {
( $capture:ident, |$( $args:ident ),*| $body:expr ) => {
|$($args)*| {
// do stuff
println!("{} got captured", stringify!(capture));
$body
}
};
( $capture:ident, $arg:expr ) => { $arg };
}
#[macro_export]
macro_rules! my_macro {
( $func:ident($( $args:expr ),*) ) => {
let to_capture = 42;
$func($(map_if_closure!(to_capture, $args)),*);
};
}
Unfortunately, this will not work because forwarding a matched fragment from my_macro
will be opaque to map_if_closure
as described here. I cannot then match the arguments as the macro will see it as a single token.
Note: I know the pattern for closures is not complete but for now it's enough.