Given an enum like
struct Earth { water: usize }
struct Mars { redness: usize }
enum World {
Mars(Mars),
Earth(Earth),
}
A common pattern I write is
fn something_expecting_mars(planet: World) {
let mars = match planet {
World::Mars(data) => data,
_ => panic!("Shouldn't be here now"),
}
}
Is there a macro I can use to expect a variant of an enum and subsequently extract its data?
// rewriting to this
let mars = expect_v!(planet, World::Mars);
The standard library provides a macro for testing a match, but not one for extracting a value. However, it's fairly easy to write one:
macro_rules! expect_v {
($e:expr, $p:path) => {
match $e {
$p(value) => value,
_ => panic!("expected {}", stringify!($p)),
}
};
}
As suggested in answers to the related question brought up in the comments, you might want to decouple value extraction from the panic. In that case, return an Option
instead and let the callers panic if they wish by calling unwrap()
:
macro_rules! extract {
($e:expr, $p:path) => {
match $e {
$p(value) => Some(value),
_ => None,
}
};
}
// ...
fn something_expecting_mars(planet: World) {
let mars = extract!(planet, World::Mars).unwrap();
}