bitfielder
Yet another bitfield library to provide bitfield access functions to underlying types.
Supports base integer types, and byte arrays as the inner base type.
But why?
One of the more common bitfield libraries, rust-bitfield uses proc-macros to define bitfield structs. This approach means higher compilation times, due to all of the build dependencies required for the bitfield-macros crate.
Also, rust-bitfield does not provide const accessor functions because of the design choice of using traits for field access.
Usage
A number of base types can be used for the inner representation of the bitfield.
Primitive integers
# use bitfielder::bitfield;
bitfield! {
pub BitfieldU8(u8): u8,
mask: 0xff,
default: 0,
{
pub range1: 7, 4;
pub range0: 3, 1;
pub bit0: 0;
}
}
(0..=u8::MAX).for_each(|bits| {
let field = BitfieldU8::from(bits);
assert_eq!(field.bit0(), bits & 0x1 != 0);
assert_eq!(field.range0(), (bits >> 1) & 0x7);
assert_eq!(field.range1(), (bits >> 4) & 0xf);
});
Byte arrays
# use bitfielder::bitfield;
bitfield! {
pub TestU8x3(LSB0 [u8; 3]): u8 {
pub range3: 23, 16;
pub range2: 15, 8;
pub range1: 7, 5;
pub range0: 4, 2;
pub bit1: 1;
pub bit0: 0;
}
}
(0..=24).map(|r| (1u32 << r) - 1).for_each(|bits| {
let [b0, b1, b2, _] = bits.to_le_bytes();
let test = TestU8x3([b0, b1, b2]);
let [b0, b1, b2] = test.bytes();
let exp_range1 = (b0 & (0x7 << 5)) >> 5;
let exp_range0 = (b0 & (0x7 << 2)) >> 2;
let exp_bit1 = ((b0 & 0x1 << 1) >> 1) != 0;
let exp_bit0 = b0 & 0x1 != 0;
assert_eq!(test.range3(), b2);
assert_eq!(test.range2(), b1);
assert_eq!(test.range1(), exp_range1);
assert_eq!(test.range0(), exp_range0);
assert_eq!(test.bit1(), exp_bit1);
assert_eq!(test.bit0(), exp_bit0);
})
User defined type field accessors
Users can supply custom types for field accessor functions.
The main constraint is the type must have the following functions:
# use bitfielder::bitfield;
# use bitfielder::result::Result;
#[derive(Debug, Eq, PartialEq)]
pub struct CustomTy(u8);
impl CustomTy {
pub const fn try_from_inner(val: u8) -> Result<Self> {
Ok(Self(val))
}
pub const fn into_inner(self) -> u8 {
self.0
}
}
bitfield! {
MacroTy: u8,
mask: 0xf,
default: 0,
{
ty_field: 3, 0;
}
}
bitfield! {
TestUser: u8,
mask: 0xff,
default: 0,
{
custom_ty: CustomTy, 7, 4;
macro_ty: MacroTy, 3, 0;
}
}
(0..=u8::MAX).for_each(|bits| {
let test = TestUser::try_from_inner(bits).unwrap();
let custom_ty = CustomTy::try_from_inner(bits >> 4).unwrap();
let macro_ty = MacroTy::try_from_inner(bits & MacroTy::MASK).unwrap();
assert_eq!(test.custom_ty(), Ok(custom_ty));
assert_eq!(test.macro_ty(), Ok(macro_ty));
})
License
This library is licensed under either MIT or APACHE-2.0.