Skip to content

Instantly share code, notes, and snippets.

@mikeyhew
Created October 6, 2017 20:04
Show Gist options
  • Save mikeyhew/102b56a5abbac91029c272714bbca577 to your computer and use it in GitHub Desktop.
Save mikeyhew/102b56a5abbac91029c272714bbca577 to your computer and use it in GitHub Desktop.
use std::fmt;
pub trait Unwrap {
type Target;
type ErrorMessage: fmt::Display;
/// takes Self and either unwraps it into Target,
/// or returns an error message to panic with
fn unwrap(self) -> Result<Self::Target, Self::ErrorMessage>;
}
macro_rules! unwrap {
($expr:expr) => {{
match $crate::Unwrap::unwrap($expr) {
Ok(x) => x,
Err(message) => {
panic!("{}", message);
}
}
}}
}
impl<T> Unwrap for Option<T> {
type Target = T;
type ErrorMessage = &'static str;
fn unwrap(self) -> Result<T, &'static str> {
match self {
Some(x) => Ok(x),
None => Err("called `Option::unwrap()` on a `None` value")
}
}
}
pub struct ResultErrorMessage<E: fmt::Debug>(E);
impl<E: fmt::Debug> fmt::Display for ResultErrorMessage<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "called `Result::unwrap()` on an `Err` value: {:?}", self.0)
}
}
impl<T, E: fmt::Debug> Unwrap for Result<T, E> {
type Target = T;
type ErrorMessage = ResultErrorMessage<E>;
fn unwrap(self) -> Result<T, Self::ErrorMessage> {
match self {
Ok(x) => Ok(x),
Err(err) => Err(ResultErrorMessage(err))
}
}
}
fn main() {
// unwrap!((&[] as &[i32]).first());
unwrap!("abc".parse::<i32>());
// if the unwrap! macro were allowed in method position, then the following
// would be equivalent:
//
// "abc".parse::<i32>().unwrap!();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment