I assume you are calling this macro at module-level, which does not allow arbitrary let-bindings. The paste crate supports case conversion, have you tried that? I.e. could you try if this creates the output you desire:
Paste is actually a function-like procedural macro under the hood, not a declarative macro. Procedural macros offer you a more flexible API and allow you to do more complex token stream manipulations than declarative macros. You could write a procedural macro yourself with the name manipulation you desire.
AFAIK the compiler does not treat procedural macros differently from declarative macros when it comes to expansion order. Expansion happens in passes, see here:
There is one further thing to note about expansion: what happens when a syntax extension expands to something that contains another syntax extension invocation. For example, consider an alternative definition of four!; what happens if it expands to 1 + three!()?
let x = four!();
let x = 1 + three!();
This is resolved by the compiler checking the result of expansions for additional syntax extension invocations, and expanding them. Thus, a second expansion step turns the above into:
let x = 1 + 3;
The takeaway here is that expansion happens in "passes"; as many as is needed to completely expand all invocations.
So your outer macro is expanded in the first pass. If the compiler discovers a second macro call inside your macro invocation (regardless whether it is a procedural or a declarative macro), it expands the second macro call in the second pass and so on.