I’ve had this macro in a library for a while:
#[macro_export]
macro_rules! match_ignore_ascii_case {
( $value: expr, $( $string: expr => $result: expr ),+ _ => $fallback: expr ) => {
{
use std::ascii::AsciiExt;
match &$value[..] {
$(
s if s.eq_ignore_ascii_case($string) => $result,
)+
_ => $fallback
}
}
};
}
It’s used like this:
match_ignore_ascii_case! { string,
"foo" => Some(Foo),
"bar" => Some(Bar),
"baz" => Some(Baz)
_ => None
}
Note that the second-to-last arm doesn’t end with a comma, while previous ones do. This is because in the macro_rules!
pattern:
( $value: expr, $( $string: expr => $result: expr ),+ _ => $fallback: expr )
… the comma is between non-fallback arms, not after them. $( … ),+
, not $( … , )+
.
I’d actually prefer to have the comma after rather than between. But when I make that change (and change the usage accordingly) I get a build error:
src/lib.rs:134:5: 134:6 error: local ambiguity: multiple parsing options: built-in NTs expr ('string') or 1 other option.
src/lib.rs:134 _ => None
^
So this macro is a bit weird, but it’s been used for about a year now.
The part where I have a problem is that recent nightlies emit a warning:
src/lib.rs:116:59: 116:60 warning: `$result:expr` may be followed by `_`, which is not allowed for `expr` fragments
src/lib.rs:116 ( $value: expr, $( $string: expr => $result: expr ),+ _ => $fallback: expr ) => {
^
src/lib.rs:116:59: 116:60 note: The above warning will be a hard error in the next release.
I think this is related to https://github.com/rust-lang/rfcs/pull/1384.
I haven’t managed to find a way to write this macro that is both “future proof” (does not emit this warning) and not ambiguous. Any suggestion?