How can I achieve the same plain-text replacement in rust?
You can't do this without a DSL macro, essentially.
C macros are token-replacement and happen before the syntax-checking step -- Rust macros are more akin to Lisp macros, which happen during the parsing step. See: https://softwareengineering.stackexchange.com/a/28387
replacing (\w+)?? with Option<$1> to simplify optional type syntax.
This also won't do what you want it to do in more complicated scenarios, such as if you have Result<T, R>?? or Vec<&'static str>?? or something like that. This is because Rust's grammar is more powerful than regexes -- it is mostly context-free with some context-sensitive parts (link).
What you're probably looking for is some sort of declarative and syntactical replacement from ($t:ty) \? \? => Option<$t>.
In addition, this regex can also probably match on non-types like a?? if a: Option<Option<T>>.
If you wanted to create a special syntax for this, you'd probably do something like:
macro_rules! shorthand_struct_fields {
/* rows of idents to types and then adjust struct definition but with T?? substituted for Option<T> */
}
struct Foo {
shorthand_struct_fields! {
x: i32??,
}
}
I'm not sure if this is such a good idea, but it you do want to create this large macro, you would be best suited by writing a declarative macros with sub-macros that use @ rules, like so: http://danielkeep.github.io/tlborm/book/pat-internal-rules.html