simplerror 1.1.0

A zero-dep macro to declaratively define error enum types and their common trait implementations.
Documentation
# 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.

```rust
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.

```rust
#[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.

```rust
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.