https://github.com/n0-computer/nested-enum-utils
Macros to provide conversions for nested enums
https://github.com/n0-computer/nested-enum-utils
Last synced: over 1 year ago
JSON representation
Macros to provide conversions for nested enums
- Host: GitHub
- URL: https://github.com/n0-computer/nested-enum-utils
- Owner: n0-computer
- License: apache-2.0
- Created: 2024-07-03T12:40:38.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-07-03T16:28:39.000Z (almost 2 years ago)
- Last Synced: 2025-02-24T00:11:35.767Z (over 1 year ago)
- Language: Rust
- Size: 12.7 KB
- Stars: 1
- Watchers: 3
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# 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