# 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