referrerpolicy=no-referrer-when-downgrade
pub trait Defensive<T> {
    // Required methods
    fn defensive_unwrap_or(self, other: T) -> T;
    fn defensive_unwrap_or_else<F>(self, f: F) -> T
       where F: FnOnce() -> 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§

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.

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

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

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

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

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() {
	 	..
}

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.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

§

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

§

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

§

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

§

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

§

fn defensive(self) -> Option<T>

§

fn defensive_proof(self, proof: &'static str) -> Option<T>

§

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

§

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

§

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

§

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

§

fn defensive(self) -> Result<T, E>

§

fn defensive_proof(self, proof: &'static str) -> Result<T, E>

Implementors§