/// Helper to simplify early returns from matches
macro_rules! patmat {
($e:expr, $pat:pat => $then:expr) => {
match $e {
$pat => Some($then),
_ => None,
}
};
($e:expr, $pat:pat => $then:expr; $or:expr) => {
match $e {
$pat => $then,
_ => $or,
}
};
}
/// Helper to support control flow with unwrapping
///
/// Usage:
///
/// ```
/// for val in &[None, Some(13)] {
/// let val = unwrap_or!(val, continue);
/// println!("{}", val);
/// }
/// ```
///
/// For non Some / Ok variants, the error can be captured with a second
/// argument. For Options this variable will always be bound to the `()`:
///
/// ```
/// for val in &[None, Some(13)] {
/// let val = unwrap_or!(val, err, {
/// println!("Got {}", err);
/// continue;
/// });
/// println!("{}", val);
/// }
/// ```
///
#[macro_export]
macro_rules! unwrap_or {
($obj:expr, $or:expr) => {
match $crate::TryOp::into_result($obj) {
Ok(obj) => obj,
Err(_) => $or,
}
};
($obj:expr, $err:ident, $or:expr) => {
match $crate::TryOp::into_result($obj) {
Ok(obj) => obj,
Err($err) => $or,
}
};
}
trait TryOp {
type Ok;
type Error;
fn into_result(self) -> std::result::Result<Self::Ok, Self::Error>;
}
impl<T> TryOp for std::option::Option<T> {
type Ok = T;
type Error = ();
fn into_result(self) -> std::result::Result<T, ()> {
self.ok_or(())
}
}
impl<T, E> TryOp for std::result::Result<T, E> {
type Ok = T;
type Error = E;
fn into_result(self) -> std::result::Result<T, E> {
self
}
}