Skip to main content

unwrap

Macro unwrap 

Source
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);