simplerror

Crates.iosimplerror
lib.rssimplerror
version1.1.0
created_at2025-02-01 06:44:54.676333+00
updated_at2025-07-04 22:55:27.180956+00
descriptionA zero-dep macro to declaratively define error enum types and their common trait implementations.
homepage
repositoryhttps://github.com/conduition/simplerror
max_upload_size
id1538241
size8,537
(conduition)

documentation

README

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.

Commit count: 2

cargo fmt