Crate simplerror

Source
Expand description

§simplerror

A zero-dependency Rust macro to declaratively define your error enums with automatic From, Display, and Error trait implementations. Declare error types which automatically wrap an inner error type while also providing detailed formatted error messages.

simplerror::declare! {
    pub enum MyError {
        SimpleMember => "something went wrong",
        SomeMember(e1: String) => "1234 {e1}",
        AnotherMember(e1: String, e2: String) => "1234 {e1} {e2}",
        BasicMember, // Display::fmt writes "MyError::BasicMember"
    }

    pub enum AnotherError {
        Variant1,
        Variant2 => "message",
        ComposedVariant(e: MyError) => "an inner error: {e}",
    }
}

assert_eq!(MyError::SimpleMember.to_string(), "something went wrong");
assert_eq!(
    MyError::SomeMember("5678".to_string()).to_string(),
    "1234 5678"
);
assert_eq!(
    AnotherError::ComposedVariant(MyError::SimpleMember).to_string(),
    "an inner error: something went wrong"
);

From implementations are handled automatically for any enum members which wrap a single value.

#[derive(Debug)]
struct Foo;

simplerror::declare! {
    pub(crate) enum CustomError {
        Failure => "We failed...",
    }

    // This enum automatically implements From<CustomError> by returning `Self::Wrapped(CustomError)`
    pub(crate) enum WrappingError {
        Wrapped(e: CustomError) => "wrapped: {e}",
    }
}

fn fail_inner() -> Result<(), CustomError> {
    Err(CustomError::Failure)
}

fn fail_outer() -> Result<(), WrappingError> {
    fail_inner()?;
    Ok(())
}

assert!(matches!(
    fail_outer(),
    Err(WrappingError::Wrapped(CustomError::Failure))
));

To derive extra traits on your error enum, or run other procedural macros, you can add them like so above each enum declaration or enum variant like so.

simplerror::declare! {
    #[derive(PartialEq)]
    #[cfg_attr(test, derive(serde::Serialize))]
    enum MyError {
        #[cfg_attr(test, serde(rename_all = "ERR_NOT_FOUND"))]
        ErrorCode404 => "didn't find it",
    }
}

impl MyError {
    fn is_404(&self) -> bool {
        self == &Self::ErrorCode404
    }
}

[!WARNING] To conditionally compile a certain enum, you can wrap the entire declare! invocation in your compilation flag.

If you conditionally compile enum members, or configure-out the enum type itself, you’ll encounter compilation errors due to missing references on the automatic trait implementations which declare! generates.

Macros§

declare
Declare error types with automatic error wrapping and trait implementations handled for you.
internal_impl_enum_from
For internal use only.