Description
It would be nice if macros could be invoked using an interpolated type from a transcription of another macro.
This is my macro to convert C typed values from an external library to Rust types:
macro_rules! c_to_rust(
($v:ident c_int) => ($v);
($v:ident *c_char) => (str::raw::from_c_str($v));
)
It works fine when invoked like c_to_rust!(i: c_int)
, but it can't be used from within another macro using an interpolated type like c_to_rust!($v: $ty)
(where the macro's invocation contains $v:ident, $ty:ty
) - probably because interpolated types cannot be matched literally in the invocation syntax.
Here's my other macro which fails to use the above one. For bindings to an external library, I need to provide a lot of callback functions. So I'm using a macro to define them, since they only differ in name and parameter types. But I want the forwarding function to convert the parameter to Rust types before passing them along, which unfortunately doesn't work. (Any hints on how to work around this are welcome, I didn't find a suitable way without repeating a lot of code)
macro_rules! forward_callback(
($fn_name:ident, $op_name:ident, $($param_name:ident: $param_type:ty),*) => (
extern fn $fn_name (userdata: *c_void, $($param_name: $param_type),*) {
unsafe {
let session: &Session = cast::transmute(userdata);
session.$op_name($(c_to_rust!($param_name: $param_type)),*);
^~~~~~~~~ FAILS
}
}
);
)
// Intended use:
forward_callback!(function1, p1: c_int)
forward_callback!(function2, p1: c_int, p2: *c_char)