There is no way to do that by itself, even with a procedural macro. This is because the macro body must still be able to be parsed to the AST, and the single quote won't let you do that.
I know it's not the correct notation, but you could do R-. That would work and could still be matched on. It shouldn't be too difficult to write, as there's not that many moves, even once you take into account rotations, wide turns, and slices.
I will note that if you intend to permit commutations, things will get a fair bit more difficult to accomplish with a macro_rules! macro.
Just a note: I'm approaching this as someone who knows the notation well and has attended a couple competitions. I suspect most people on this forum don't have knowledge of both cubing and Rust macros.
Using a lifetime would work, but doing so would require whitespace before it. It's quite common to not have whitespace in notation.
Thanks for all the input! I didn't think about it from the view of the AST. From that point of view, it's obvious that using macros wouldn't work. It's more important to me to be able to keep the ' than to not surround things with some "s. Plus, then I can write functions instead of macros, haha
There is another option, in principle: write a macro that takes a path to a file containing code writteb in your DSL, opens and reads that file, parses and processes the DSL code within, and then proceeds as a normal macro would.
This would give you:
The ability to use A' as an identifier
The ability to avoid putting that in a string
And the cost would be:
You'd need to write a grammar or parser (eg using pest, nom etc) rather than bring able to rely on e.g. the syn and quote crates. This is so that you can define your identifier format to allow ending in 0 or more ', eg the tegex [A-Za-z_][A-Za-z0-9_]*\'*
An inability to write inline code (i.e. code located within a .rs file) that is not encased in a Rust string