Macro dyn_error::impl_err_equality

source ·
macro_rules! impl_err_equality {
    (
        // The existing type for which the equality checks must be defined
        $type: tt
    ) => { ... };
}
Expand description

Given an existing type E implementing the Error and PartialEq traits, automatically provides an implementation for the following equality checks and for the symmetric ones:

  • E == Box<E>, returning true if the boxed E equals the given one.

  • E == Box<dyn Error>, returning true if the boxed error is of type E and actually equals the given one.

  • E == Result<_, E>, returning true if the Result is Err and its wrapped error equals the given one.

  • E == Result<_, Box<E>>, returning true if the Result is Err and the boxed error equals the given one.

  • E == Result<_, Box<dyn Error>>, returning true if the Result is Err, while the boxed error is of type E and equals the given one.

use dyn_error::impl_err_equality;
use std::error::Error;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
enum MyError {
    First,
    Second
}

impl std::fmt::Display for MyError {
   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
       write!(
           f,
           "{}",
           match self {
               Self::First => "First error".to_string(),
               Self::Second => "Second error".to_string(),
           }
      )
   }
}

impl Error for MyError {}

impl_err_equality!(MyError);


// Ensuring E == E
assert_eq!(MyError::First, MyError::First);

// Checking E == Box<E> (and vice versa)
assert_eq!(MyError::First, Box::new(MyError::First));
assert_eq!(Box::new(MyError::First), MyError::First);

// Checking E == Box<dyn Error> (and vice versa)
let dyn_box: Box<dyn Error> = Box::new(MyError::First);
assert_eq!(MyError::First, dyn_box);
assert_eq!(dyn_box, MyError::First);

// Checking E == Result<_, E> (and vice versa)
let result_with_err: Result<u8, MyError> = Err(MyError::First);
assert_eq!(MyError::First, result_with_err);
assert_eq!(result_with_err, MyError::First);

// Checking E == Result<_, Boxed<E>> (and vice versa)
let result_with_boxed_err: Result<u8, Box<MyError>> = Err(Box::new(MyError::First));
assert_eq!(MyError::First, result_with_boxed_err);
assert_eq!(result_with_boxed_err, MyError::First);   
     
// Checking E == Result<_, Boxed<dyn Error>> (and vice versa)
let result_with_boxed_dyn_err: Result<u8, Box<dyn Error>> = Err(Box::new(MyError::First));
assert_eq!(MyError::First, result_with_boxed_dyn_err);
assert_eq!(result_with_boxed_dyn_err, MyError::First);