I am not really sure what the correct syntax of the matches! macro is. Say I have an enum like
enum Test {
A {
value: i32
}
}
Now I know that I can match the values like following
let t = Test::A { value: 42 };
match t {
Test::A { value } if value > 40 => {
println!("Greater than 40");
},
Test::A { value } => {
println!("{}", value);
}
}
where the first guard could be asserted with
assert!(matches!(t, Test::A { value } if value > 40 ));
but can I also assert the second guard? Shouldn't this be possible?:
assert!(matches!(t, Test::A { value } => { ... }));
match expressions consider each pattern+guard in order. So the second match arm, Test::A { value } => { ... } is only reached if the first one fails to match. This means you could use something like
assert!(matches!(t, Test::A { value } if value <= 40 ));
in your example.
Note on terminology:
“Test::A { value }” is a pattern,
“if value > 40” is a guard (or match guard)
“Test::A { value } if value > 40 => { println!("Greater than 40"); }” is a match arm
“Test::A { value } => { println!("{}", value); }” is a match arm, too. This one does not contain a guard at all.
so
you might mean “the second match arm”, i.e. “can I also assert the second match arm is taken?”
In general (as an approach that’s not specific to this example), you could assert the first pattern+guard does not match, and assert that the second one does match, something like
assert!(!(matches!(t, Test::A { value } if value > 40 )) && matches!(t, Test::A { value })
If, as is the case here, the second arm is also the last arm, so it’s just about not taking the first arm, then you can shorten it to
assert!(!(matches!(t, Test::A { value } if value > 40 )))
or
assert!(!matches!(t, Test::A { value } if value > 40 ))
Oh, ok so the macro expects guards but I'm providing a match arm.
assert!(matches!(t, Test::A { value } => { ... }));
Is there any way to test pseudo-code like this then in a clean way? I would like to test whether something is a specific enum variant and then further test the values this enum variant encloses.