bitfielder 0.1.1

Yet another bitfield library
Documentation
# 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).