Reputation:
So i have this macro thats used to match Box<dyn error::Error>
against multiple error types
#[macro_export]
macro_rules! dynmatch {
($e:expr, $(type $ty:ty {$(arm $pat:pat => $result:expr),*, _ => $any:expr}),*, _ => $end:expr) => (
$(
if let Some(e) = $e.downcast_ref::<$ty>() {
match e {
$(
$pat => {$result}
)*
_ => $any
}
} else
)*
{$end}
);
}
It was working fine until i tried adding match gaurds. when i try using "if" statements in the pattern it gives me the error no rules expected the token 'if'
let _i = match example(2) {
Ok(i) => i,
Err(e) => {
dynmatch!(e,
type ExampleError1 {
arm ExampleError1::ThisError(2) => panic!("it was 2!"),
_ => panic!("{}",e)
},
type ExampleError2 {
arm ExampleError2::ThatError(8) => panic!("it was 8!"),
arm ExampleError2::ThatError(9..=11) => 10,
_ => panic!("{}",e)
},
type std::io::Error {
arm i if i.kind() == std::io::ErrorKind::NotFound => panic!("not found"), //ERROR no rules expected the token `if`
_ => panic!("{}", e)
},
_ => panic!("{}",e)
)
}
};
Is there any way to use match guards in my pattern matching without getting token errors?
Upvotes: 0
Views: 135
Reputation:
and of course, even though i spent like an hour looking for a solution, right after i post this question i find an answer.
the correct macro looks like:
#[macro_export]
macro_rules! dynmatch {
($e:expr, $(type $ty:ty {$(arm $( $pattern:pat )|+ $( if $guard: expr )? => $result:expr),*, _ => $any:expr}),*, _ => $end:expr) => (
$(
if let Some(e) = $e.downcast_ref::<$ty>() {
match e {
$(
$( $pattern )|+ $( if $guard )? => {$result}
)*
_ => $any
}
} else
)*
{$end}
);
}
credit to the rust matches! source lines 244-251
Upvotes: 2