MaikKlein / enumflags

24 stars 7 forks source link

Multiple Bits for Flag #7

Open robbym opened 7 years ago

robbym commented 7 years ago
#[derive(EnumFlags, Copy, Clone, Debug)]
#[repr(u8)]
pub enum GeneralStatus {
    INDICATOR_IDENTIFY    = 0b01000000,
    INDICATOR_MUTE        = 0b10000000,
    INDICATOR_NORMAL      = 0b11000000,

    PORT_AUTH_PANEL       = 0b00010000,
    PORT_AUTH_NETWORK     = 0b00100000,

    BOOT_ROM              = 0b00000100,
    RDM_CAPABLE           = 0b00000010,
    UBEA_PRESENT          = 0b00000001,
}

Gives the error:

The following flags are not unique: ["GeneralStatus::INDICATOR_IDENTIFY = 0b1000000", "GeneralStatus::INDICATOR_MUTE = 0b10000000", "GeneralStatus::IND
ICATOR_NORMAL = 0b11000000"]

Is this not possible? I can't change how these bits are laid out as they are part of an existing network protocol.

MaikKlein commented 7 years ago

I have thought about that problem before and I am not sure what the best approach would be. I probably could add an option to allow duplicates.

Alternatively INDICATOR_NORMAL can be put outside of the enum, maybe in a function because it is just INDICATOR_IDENTIFY | INDICATOR_MUTE

Something like

impl GeneralStatus{
    pub fn normal() -> BitFlags<GeneralStatus> {
        GeneralStatus::INDICATOR_IDENTIFY | GeneralStatus::INDICATOR_MUTE
    }
}
robbym commented 7 years ago

Ideally, I would like to specify which parts of a bitfield can be orred together. In my case is doesn't make sense. INDICATORIDENTIFY can't be orred with an other INDICATOR, but can with the at least 1 PORT_, and any number of (BOOT_RDM, RDM_CAPABLE, or UBEA_PRESENT).

Not sure if that sort of feature should belong in this crate though. IDK

robbym commented 7 years ago

I just tried sketching out what I wanted but it turns out I'd need powerset(n) types that each implemented BirOr for each type to do this.

MaikKlein commented 7 years ago

Ideally, I would like to specify which parts of a bitfield can be orred together. In my case is doesn't make sense. INDICATORIDENTIFY can't be orred with an other INDICATOR, but can with the at least 1 PORT_, and any number of (BOOT_RDM, RDM_CAPABLE, or UBEA_PRESENT). Not sure if that sort of feature should belong in this crate though. IDK

Ah, I am not sure that I can easily support this use case. At least I don't see an obvious API for it. I think if I would want this to be type safe I would create another wrapper on top of it that manages the indicator bits separately.