Devlyn-Nelson / Bondrewd

Rust proc_macro library for bit level field packing.
7 stars 2 forks source link

Add in support for Enum Variant Discriminants #4

Closed james-womack closed 2 years ago

james-womack commented 2 years ago

Adds in support for Enum Variant Discriminants when parsing into/from bytes. For example, the following is now supported:

#[derive(Eq, PartialEq, Clone, Debug, BitfieldEnum)]
#[bondrewd_enum(u8)]
enum CustomEnum {
    CustomZero = 0x30,
    CustomOne = 0x10,
    CustomTwo = 0x20,
    CustomThree = 0x40,
    Invalid,
}

#[derive(Bitfields, Clone, PartialEq, Eq, Debug)]
#[bondrewd(default_endianness = "be")]
struct CustomEnumUsage {
    one: u8,
    #[bondrewd(enum_primitive = "u8", bit_length = 8)]
    two: TestCustomEnum,
    three: u8,
}

fn main() {
    let simple = CustomEnumUsage {
        one: 0x08,
        two: CustomEnum::CustomThree,
        three: 0,
    };
    let bytes = simple.clone().into_bytes();
    assert_eq!(bytes[1], 0b01000000); // Same as 0x40 (CustomEnum::CustomThree)
}

This also supports continuation of discrimination value in successive variants, replicating Rust behavior like:

#[derive(Eq, PartialEq, Clone, Debug, BitfieldEnum)]
#[bondrewd_enum(u8)]
enum CustomContinuationEnum {
    CustomZero = 0x7F,
    CustomZeroContinued,
    CustomOne = 0x3F,
    CustomOneContinued,
    Invalid,
}

#[derive(Bitfields, Clone, PartialEq, Eq, Debug)]
#[bondrewd(default_endianness = "be")]
struct CustomContinuationEnumUsage {
    one: u8,
    #[bondrewd(enum_primitive = "u8", bit_length = 8)]
    two: CustomContinuationEnum,
    three: u8,
}

fn main() {
    let simple = CustomContinuationEnumUsage {
        one: 0x80,
        two: CustomContinuationEnum::CustomOneContinued,
        three: 0x08
    };
    let mut bytes = simple.clone().into_bytes();
    assert_eq!(bytes[1], 0b01000000);
}

(See: tests/enum_fields_custom.rs for more details)