I wrote a macro but now I am trying to extend it so I can pass it a function. I read the Rust Reference and I don't really understand metavariables. I feel like everything I want is going to be an expression, but how can I pass error
to an expression without breaking everything?
macro_rules! unwrap_or_return {
( $a:expr, $b:expr ) => {
match $a {
Ok(x) => x,
Err(_) => return Err($b),
}
};
// new part
( $a:expr, $fun:FUNCTION ) => {
match $a {
Ok(x) => x,
Err(error) => return Err($fun(error)),
}
};
}
macro_rules! unwrap_or_return {
// This needs to go fist since is's more specific version of expression branch below would
// make this one unreachable if preceded.
//
// What I ve done here is something that looks like a closure to the user and is probably what
// you want. The metavariables are something predefined by rust and they simply capture some
// portion of syntax. In this case, $p captures a closure or function parameter syntax which we
// can inject into error pattern. Since the $p is written by the user, the identifier is
// visible to to other code made by user.
($a:expr, |$p:pat_param| $body:expr) => {
match $a {
Ok(x) => x,
Err($p) => return Err($body.into()),
}
};
($a:expr, $b:expr) => {
match $a {
Ok(x) => x,
Err(_) => return Err($b.into()),
}
};
}
fn example() -> Result<(), String> {
let a = Ok::<usize, String>(1);
let b = Err("error".to_string());
let _x = unwrap_or_return!(a, "error");
let _y = unwrap_or_return!(b, |e| format!("error: {}", e));
Ok(())
}