bitfielder

Crates.iobitfielder
lib.rsbitfielder
version0.1.1
created_at2025-08-22 20:26:14.038644+00
updated_at2025-08-23 22:44:28.292544+00
descriptionYet another bitfield library
homepage
repositoryhttps://codeberg.org/weathered-steel/bitfielder
max_upload_size
id1806877
size67,130
Weathered Steel (weathered-steel-org)

documentation

README

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! {
        /// 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

    # 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:

    # 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 or APACHE-2.0.

Commit count: 0

cargo fmt