Is it possible to write a Rust macro that will expand into a function / method signature?

I would like to be able to do something like the following:

macro_rules! impl_a_method( ($obj:ident, $body:block) => ( fn a_method(foo: Foo, bar: Bar, baz: Baz) -> $obj $body ) ) // Implementation would look like: impl_a_method!(MyType, { MyType { foo: foo.blah(), bar: bar.bloo(), baz: baz.floozy(), } }) 

In my real world, there are methods with much larger signatures that I have to implement in unique ways for 30+ different types.

I tried something similar to the above macro, however I encounter errors when rustc considers foo , bar and baz unresolved names on the extension site (although I am sure that the macro declaration is lexically preceded by use).

Is it possible to do something like this?

If not, can you recommend an approach that would achieve something like this?

+6
source share
1 answer

This is not possible due to macro hygiene. Any identifier entered into the macro body is guaranteed to be different from any identifier on the macro invocation site. You must provide all the identifiers yourself, which somewhat does not match the purpose of the macro:

 impl_a_method!(MyType, (foo, bar, baz), { MyType { foo: foo.blah(), bar: bar.bloo(), baz: baz.floozy(), } }) 

This is done using this macro:

 macro_rules! impl_a_method( ($obj:ty, ($_foo:ident, $_bar:ident, $_baz:ident), $body:expr) => ( fn a_method($_foo: Foo, $_bar: Bar, $_baz: Baz) -> $obj { $body } ) ) 

The only thing you really save here is write the parameter types of the method.

+5
source

Source: https://habr.com/ru/post/972686/


All Articles