Macro tear::tear[][src]

macro_rules! tear {
    ( $e:expr ) => { ... };
    ( $e:expr => $f:expr ) => { ... };
}

Turns a ValRet into a value or an early return

It also coerces its argument to a ValRet (Return trait).

Description

let x = tear! { $e };

If $e is Val(v), then v is assigned to x. Otherwise it is Ret(r), in which case the function immediately returns with a value of r.

This macro is useful when you have functions that return ValRet.

let x = tear! { $e => $f }

Same as the previous form, but the return value r is first mapped through $f before returning. In short, we return $f(r).

Additionally, both forms make use of the convert::From trait to automatically convert the value when returning it. This behaviour is the same as the try operator ?. You may need to be more specific with type annotations so that the compiler can infer the right types.

Examples

tear! with Val and Ret.

// "Ian" is assigned to name
let name = tear! { Val::<_, ()>("Ian") };

// The function immediately returns -1
let _ = tear! { Ret(-1) };

tear! with a function returning ValRet

fn get_name () -> ValRet<String, i32> {
    Val("Chris".to_string())
    // or Ret(0)
}

fn func () -> i32 {
    // Will either assign the value to name, or return immediately
    let name = tear! { get_name() };
    name.len() as i32
}

Mapping the return value

fn string_id(s: OsString) -> String {
    let s: String = tear! { s.into_string() => |_| "No ID".to_string() };
    let id = s.len().to_string();
    id
}

Automatic conversion with convert::From

#[derive(Debug, PartialEq, Eq)]
struct MyInt(u8);
impl std::convert::From<u8> for MyInt {
    fn from(x :u8) -> Self { Self(x) }
}

fn five_as_myint() -> MyInt {
    tear! { Ret(5) }
}

assert_eq![ five_as_myint(), MyInt(5) ];

Naming

The name “tear” comes from the image of tearing apart the the usable value from the early return. It also happens to be that “tear” looks like “ret(urn)” backwards.