Native Rust macros are generally preferred, because they prevent a few classes of error that can happen with the purely textual macros cpp and m4 use. In particular, they prevent unpaired delimiters from appearing in the macro expansion and name collisions between the macro implementation and the callsite.
You can use both. You can run them more than once, perhaps changing the source with a sed or perl script between passes.