nested_enum_utils 0.1.0

Macros to provide conversions for nested enums
Documentation
# Nested enum utils

This crate provides a single attribute macro to provide conversions from enum cases to the enum itself or to some other type.

It only works with enums where each variant has a single unnamed element, and if each variant has a distinct type.

The most basic use is to provide conversions between the enum cases and the enum type itself. You could achieve something similar with the popular [derive_more] crate.

```rust
#[enum_conversions()]
enum Request {
  Get(GetRequest),
  Put(PutRequest),
}
```

A more advanced use, and the reason for this crate to exist, is to provide conversions between enum variants and any type that itself has a *conversion* to the enum. This allows to use nested enums, like you would in a complex protocol that has several subsystems.

```rust
#[enum_conversions(Request)]
enum StoreRequest {
  Get(GetRequest),
  Put(PutRequest),
}

#[enum_conversions(Request)]
enum NetworkRequest {
  Ping(PingRequest),
}

#[enum_conversions()]
enum Request {
  Store(StoreRequest),
  Network(NetworkRequest),
}
```

Here we define conversions from `GetRequest` to `StoreRequest`, from `StoreRequest` to `Request`, and then directly from `GetRequest` to `Request`, and corresponding [TryFrom] conversions in the other direction.

## Generated conversions

The generated [From] conversions are straightforward. Obviously it is always possible to convert from an enum case to the enum itself.

We also generate [TryFrom] conversions from the enum to each variant, as well as from a reference to the enum to a reference to the variant.

The conversions that take a value are different than the ones from [derive_more]: they return the unmodified input in the error case, allowing to chain conversion attempts.

```rust
let request = ...
match GetRequest::try_from(request) {
  Ok(get) => // handle get request
  Err(request) => {
    // I still got the request and can try something else
    match PutRequest::try_from(request) {
      ...
    }
  }
}
```

The conversions that take a reference just return a `&'static str` as the error type. References are `Copy`, so we can always retry anyway.

[From]: https://doc.rust-lang.org/std/convert/trait.From.html
[TryFrom]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html
[derive_more]: https://crates.io/crates/derive_more