# 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](https://docs.rs/bitfield) uses [proc-macros](https://doc.rust-lang.org/reference/procedural-macros.html) 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](https://docs.rs/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
```rust
# use bitfielder::bitfield;
bitfield! {
/// U8 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
```rust
# use bitfielder::bitfield;
bitfield! {
/// Test 24-bit array.
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:
```rust
# 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> {
// example only, provide your own logic for type validation
Ok(Self(val))
}
pub const fn into_inner(self) -> u8 {
self.0
}
}
// Use the library macro to define a custom field type.
bitfield! {
/// Custom macro field type.
MacroTy: u8,
mask: 0xf,
default: 0,
{
ty_field: 3, 0;
}
}
bitfield! {
/// Test User defined fields.
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](LICENSE-MIT) or [APACHE-2.0](LICENSE-APACHE).