illicitonion / num_enum

Apache License 2.0
264 stars 34 forks source link

Add discriminant derive #119

Open RReverser opened 1 year ago

RReverser commented 1 year ago

I'm often running into a case where I'd want to derive discriminant on arbitrary enums. It's even more useful nowadays now that arbitrary_enum_discriminants are stabilized in Rust, so you can customize them and not only use the default order.

For example, deriving errors with associated error codes could then look like:

use num_enum::PrimitiveDiscriminant;
use displaydoc::Display;
use thiserror::Error;

#[derive(Display, Debug, Error, PrimitiveDiscriminant)]
#[repr(u16)]
pub enum DataStoreError {
    /// data store disconnected
    Disconnect(#[source] io::Error) = 0x201,
    /// the data for key `{0}` is not available
    Redaction(String) = 0x205,
    /// invalid header (expected {expected:?}, found {found:?})
    InvalidHeader {
        expected: String,
        found: String,
    } = 0x300,
    /// unknown data store error
    Unknown = 0,
}

fn print_err(err: &DataStoreError) {
  eprintln!("Error #{:X}: {}", err.discriminant(), err);
}

This crate seems like the perfect fit for it since it has all the necessary machinery for dealing with discriminant on enums and would only need one extra trait+derive for the non-owned version of IntoPrimitive.