How can I make the => $ret:ty optional when calling the macro, and use () for $ret type when omitted? http://dpaste.com/108HTH7
By optional I mean "on a per $fn basis" (not either omitted for all or given for all).
So that e.g. line 48, 69 and 81 can be written without => ().
Is it possible?
As you can see I need all $fns inside the macro body to generate the struct members..
With that syntax? You'd need an incremental parser, which would not be a lot of fun.
If you change the syntax so that the function type is inside a group (i.e.(), [], or {}), you can blindly match the whole group, then feed that to a different macro that can distinguish between "has trailing return type" and not on a fn-by-fn basis.
Or you could just write the => () out and keep the macro simple.
If a caller of the macro writes more than one => $ret, it will match this pattern but fail to compile anyway because the macro would expand to invalid syntax.
There is a $()? matcher in the nightly compiler which accepts 0 or 1 of its contents, so in the future you would use $(=> $ret:ty)?. Tracked in rust-lang/rust#48075.
Why does it need to be in a group, why can't I just match tokens until each ;? Like ($($($tok:tt)+;)+) => ... and then delegate $($tok)+?
If I was using a group, how should I match the inner stuff if not with this?: ($([$($tok:tt)+])+) => ...
@dtolnay Thanks! And then, how can I conditionally use () as default return type? Should I make a new sub-macro (or internal branch with @foo) that has 2 cases to match each one and then delegate to that sub-macro for generating the stuff in line 3 and line 12-17?
Because the macro matcher isn't that clever. As soon as you start a $($tok:tt)*, it will eat everything until the end of the current token group.
My point about using a group was so that you delegate parsing the function arguments to another macro, which can just have two rules: one for functions with a return type, one for functions without.
... but then dtolnay reminded me that in this case you should be able to get away with a repetition match on the => $ret:ty bit. And yes, you'd want to delegate to another macro or sub-rule that expands (=> $ret:ty) => {$ret} or () => {()}.
Ah yes, thanks
I'm using $(-> $ret)? in the expansion now.
Btw, when to use $(..)+in the expansion and when $(..)*?
Should I use the same that I used for matching in the args?
But I was using $(..)* to expand stuff matched with $(..)+ and it didn't complain..