macro_rules! unwrap {
($expr:expr, |$binding:pat_param| $action:expr $(,)?) => { ... };
($expr:expr, $action:expr $(,)?) => { ... };
}Expand description
{Option,Result}::unwrap() while handling errors
This has an advantage over other methods such as
Option::unwrap_or_else() and
Result::unwrap_or_else() because it expands the
provided code into the same scope as the call, allowing you to do things like return, break,
or continue that would not be possible inside of a closure.
While the syntax might look like a closure, it is NOT. The reason this syntax was chosen was
so that rustfmt is able to format the macro body because it sees it as valid rust code (an
expression + a closure).
ยงExamples
use std2::unwrap;
fn do_something(res: Result<u8, &'static str>) -> u8 {
let x = match res {
Ok(x) => x,
Err(err) => {
println!("error: {err}");
return 0;
}
};
x + 2
}
fn do_something2(res: Result<u8, &'static str>) -> u8 {
let x = unwrap!(res, |err| {
println!("error: {err}");
// this returns 0 from the function (`do_something2`)
// it does NOT assign 0 to `x`
return 0;
});
x + 2
}
assert_eq!(do_something(Ok(2)), 4);
assert_eq!(do_something2(Ok(2)), 4);
assert_eq!(do_something(Err("oops")), 0);
assert_eq!(do_something2(Err("oops")), 0);