I have a use case where I have large enums that represent integer values of an existing protocol as u8, u16 and u32 respectively. Let's assume one of the nested u8 enums.
It contains various error states, some of which belong to logical sub-groups. Hence I extracted those into appropriate sub-enums. Here's a conceptual example:
I currently work around the problem, that I cannot translate those values directly via as by using manual implementations of From and TryFrom or num_traits::FromPrimitive respectively.
However, this requires me to specify the assigned values now multiple times i.e. in the From for enum -> int implementation and in the TryFrom implementation for int -> enum conversion (and - now optionally in the enums itself).
This of course is bad, since it is duplicated code and may lead to inconsistencies (when accidentally swapping a value in one of the conversion traits).
My question thus is, is there a way to define nested enums with assigned integer values without such repetition?
This seems to require that I derive Default in the nested enum and only ever loads that specified default instead of the variant with the respective value.
~/nested_enums> cargo run
Compiling nested_enums v0.1.0 (/home/neumann/nested_enums)
error[E0277]: the trait bound `SpammError: Default` is not satisfied
--> src/main.rs:3:10
|
3 | #[derive(FromRepr)]
| ^^^^^^^^ the trait `Default` is not implemented for `SpammError`
|
= note: this error originates in the derive macro `FromRepr` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused variable: `e`
--> src/main.rs:21:9
|
21 | let e = Error::from_repr(5); // Expected Ok(Error::Spamm(SpammError::SpammIsEggs))
| ^ help: if this is intentional, prefix it with an underscore: `_e`
|
= note: `#[warn(unused_variables)]` on by default
For more information about this error, try `rustc --explain E0277`.
warning: `nested_enums` (bin "nested_enums") generated 1 warning
error: could not compile `nested_enums` (bin "nested_enums") due to 1 previous error; 1 warning emitted
That derive macro is primarily intended to be used with unit-like variants, with the assumption that any associated data is actual associated data and not just another, nested discriminant in disguise.
You would be better off creating a flattened representation and then creating conversion methods from/to the nested representation.