1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//! Home of [`UnwrapOrRevert`](crate::unwrap_or_revert::UnwrapOrRevert), a convenience trait for
//! unwrapping values.

use crate::contract_api::{runtime, Error};

/// A trait which provides syntactic sugar for unwrapping a type or calling
/// `runtime::revert()` if this fails.  It is implemented for `Result` and `Option`.
pub trait UnwrapOrRevert<T> {
    /// Unwraps the value into its inner type or calls `runtime::revert()` with a
    /// predetermined error code on failure.
    fn unwrap_or_revert(self) -> T;

    /// Unwraps the value into its inner type or calls `runtime::revert()` with the
    /// provided `error` on failure.
    fn unwrap_or_revert_with<E: Into<Error>>(self, error: E) -> T;
}

impl<T, E: Into<Error>> UnwrapOrRevert<T> for Result<T, E> {
    fn unwrap_or_revert(self) -> T {
        self.unwrap_or_else(|error| runtime::revert(error.into()))
    }

    fn unwrap_or_revert_with<F: Into<Error>>(self, error: F) -> T {
        self.unwrap_or_else(|_| runtime::revert(error.into()))
    }
}

impl<T> UnwrapOrRevert<T> for Option<T> {
    fn unwrap_or_revert(self) -> T {
        self.unwrap_or_else(|| runtime::revert(Error::None))
    }

    fn unwrap_or_revert_with<E: Into<Error>>(self, error: E) -> T {
        self.unwrap_or_else(|| runtime::revert(error.into()))
    }
}