I'm creating a macro that matches two expressions and an identifier. I would like to be able to ignore the identifier if it's not needed, but the compiler seems to complain if I use _
there.
My macro:
macro_rules! if_some {
($x:expr, $id:ident, $expr:expr) => {
match $x {
None => None,
Some($id) => Some($expr),
}
};
}
What I'd like to do:
if_some!(obtain_an_option(), x, do_something_with(x))
and
if_some!(obtain_an_option(), _, do_something())
The second call fails.
I worked around it by defining a second macro if_some_!
that doesn't receive an identifier (I could not use a second pattern either). I'm sure there's a way to say "here accept an identifier or just _
.
Maybe there's already a macro/function for this (like Option::map
now I think about it)... nevertheless it'd be nice to now.
Option::map
seems to be the best solution for this particular problem, but when you really need a macro which expect both idents and _
as a pattern, you can also use the $p:pat
fragment. The fragment of course accepts a broader range of patterns like (ref x, y)
, but typically this will be acceptable.
macro_rules! if_some {
($x:expr, $p:pat, $expr:expr) => {
match $x {
None => None,
Some($p) => Some($expr),
}
};
}
fn main() {
println!("{:?}", if_some!(Some(12), x, x + 1)); // Some(13)
println!("{:?}", if_some!(Some(12), _, 1)); // Some(1)
}