pub trait Defensive<T> {
    // Required methods
    fn defensive_unwrap_or(self, other: T) -> T;
    fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T;
    fn defensive_unwrap_or_default(self) -> T
       where T: Default;
    fn defensive(self) -> Self;
    fn defensive_proof(self, proof: &'static str) -> Self;
}
Expand description

A trait to handle errors and options when you are really sure that a condition must hold, but not brave enough to expect on it, or a default fallback value makes more sense.

This trait mostly focuses on methods that eventually unwrap the inner value. See DefensiveResult and DefensiveOption for methods that specifically apply to the respective types.

Each function in this trait will have two side effects, aside from behaving exactly as the name would suggest:

  1. It panics on #[debug_assertions], so if the infallible code is reached in any of the tests, you realize.
  2. It will log an error using the runtime logging system. This might help you detect such bugs in production as well. Note that the log message, as of now, are not super expressive. Your best shot of fully diagnosing the error would be to infer the block number of which the log message was emitted, then re-execute that block using check-block or try-runtime subcommands in substrate client.

Required Methods§

source

fn defensive_unwrap_or(self, other: T) -> T

Exactly the same as unwrap_or, but it does the defensive warnings explained in the trait docs.

source

fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T

Exactly the same as unwrap_or_else, but it does the defensive warnings explained in the trait docs.

source

fn defensive_unwrap_or_default(self) -> Twhere T: Default,

Exactly the same as unwrap_or_default, but it does the defensive warnings explained in the trait docs.

source

fn defensive(self) -> Self

Does not alter the inner value at all, but it will log warnings if the inner value is None or Err.

In some ways, this is like .defensive_map(|x| x).

This is useful as:

if let Some(inner) = maybe_value().defensive() {
	 	..
}
source

fn defensive_proof(self, proof: &'static str) -> Self

Same as Defensive::defensive, but it takes a proof as input, and displays it if the defensive operation has been triggered.

Implementations on Foreign Types§

source§

impl<T> Defensive<T> for Option<T>

source§

fn defensive_unwrap_or(self, or: T) -> T

source§

fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T

source§

fn defensive_unwrap_or_default(self) -> Twhere T: Default,

source§

fn defensive(self) -> Self

source§

fn defensive_proof(self, proof: &'static str) -> Self

Implementors§

source§

impl<T, E: Debug> Defensive<T> for Result<T, E>