Skip to content

Releases: wrenger/bitfield-struct-rs

0.7.0

07 Jun 12:45
Compare
Choose a tag to compare

This release adds a new way to specify the memory layout of the bitfield via the repr attribute. This makes it possible to specify the endianness for the whole bitfield as shown below.

use endian_num::be16;

#[bitfield(u16, repr = be16, from = be16::from_ne, into = be16::to_ne)]
struct MyBeBitfield {
    #[bits(4)]
    first_nibble: u8,
    #[bits(12)]
    other: u16,
}

let my_be_bitfield = MyBeBitfield::new()
    .with_first_nibble(0x1)
    .with_other(0x234);
assert_eq!(my_be_bitfield.into_bits().to_be_bytes(), [0x23, 0x41]);

Here, the Bitfield is represented as an be16 integer in memory. All the conversion is done automatically by calling from and into.

Thanks to @mkroening for implementing and documenting this feature (#39, #41).

0.6.2

23 May 11:25
Compare
Choose a tag to compare

In this tiny release, we added documentation to conversion functions to stop the Rust from complaining with #![warn(missing_docs)].

Thanks to @osteffenrh for fixing this (#37)

0.6.1

14 Apr 12:53
Compare
Choose a tag to compare

This minor release just fixes #35 (raw field names) and #36 (failing overflow tests).
Thanks to @osteffenrh and @marcfir for reporting them.

The first issue reported a bug when using r# raw identifiers, as shown below. This is now supported.

#[bitfield(u8)]
#[derive(PartialEq)]
struct Raw {
    r#type: u8,
}
let raw = Raw::new().with_type(0xff);
assert_eq!(raw.r#type(), 0xff);

0.6.0

16 Feb 22:43
Compare
Choose a tag to compare

This release added the auto-generation of the (from|into)_bits conversion functions for bitfields (which can be disabled by [bitfield(u8, conversion = false)]).

Together with the laxer type requirements for the conversion functions, this makes it simple to nest bitfields.

#[bitfield(u8)]
#[derive(PartialEq)]
struct Child {
    contents: u8,
}
#[bitfield(u16)]
#[derive(PartialEq)]
struct Parent {
    #[bits(8)]
    child: Child,
    other: u8,
}
let child = Child::new().with_contents(0xff);
let parent = Parent::new().with_child(child);
assert_eq!(child.into_bits(), 0xff);
assert_eq!(parent.into_bits(), 0xff);

Thanks to @Frostie314159 for implementing this feature and to @akauppi and @deeglaze for additional fixes.

0.5.6

10 Dec 23:26
Compare
Choose a tag to compare

This release introduces a new parameter to the #[bits] attribute for making fields read-only or write-only.

#[bitfield(u16)]
struct MyBitfield {
    #[bits(8, access = RO)]
    read: u8,
    #[bits(8, access = WO)]
    write: u8,
}

let v = MyBitfield::new().with_write(0xea);
assert_eq!(v.0, 0xea00);
assert_eq!(v.read(), 0);

Thanks to @paul1999 for implementing this feature.

0.5.5

11 Nov 20:23
Compare
Choose a tag to compare

This release fixes two issues (#22 and #24) related to the bounds check for signed integers.

Thanks to @jerrinot and @snakehand for finding and investigating them.

0.5.4

31 Aug 09:12
Compare
Choose a tag to compare

This minor release adds the #[track_caller] attribute to the setter functions, making it easier to figure out where a value overflows (#20).

Thanks to @rj00a for implementing this feature.

0.5.3

30 Jul 13:07
Compare
Choose a tag to compare

In this release, we have a new option for the bit order.
The fields can now be ordered beginning with the most significant bits first, as shown below.

# use bitfield_struct::bitfield;
#[bitfield(u8, order = Msb)]
struct MyMsbByte {
    /// The first field occupies the most significant bits
    #[bits(4)]
    kind: usize,
    system: bool,
    #[bits(2)]
    level: usize,
    present: bool
}
let my_byte_msb = MyMsbByte::new()
    .with_kind(10)
    .with_system(false)
    .with_level(2)
    .with_present(true);
//                         .- kind
//                         |    .- system
//                         |    | .- level
//                         |    | |  .- present
assert!(my_byte_msb.0 == 0b1010_0_10_1);

Thanks to @pwfff for implementing this feature.

0.5.2

27 Jun 20:58
Compare
Choose a tag to compare

Add the option to opt out from implementing the Default trait similar to the fmt::Debug trait.

#[bitfield(u64, debug = false, default = false)]
struct CustomDebug {
    data: u64
}
impl fmt::Debug for CustomDebug {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "0x{:x}", self.data())
    }
}
impl Default for CustomDebug {
    fn default() -> Self {
        Self(123) // note: you can also use `#[bits(64, default = 123)]`
    }
}

let val = CustomDebug::default();
println!("{val:?}")

0.5.1

27 Jun 20:17
Compare
Choose a tag to compare

This release redesigned the support for custom types.
They are now also const (compile time evaluated) but require conversion functions (from_bits/into_bits; this can be changed in the attribute parameters). Beware, this breaks compatibility with the previous From/Into based implementation.

Similarly, the fields can now specify custom defaults in the bits attribute like #[bits(7, default = 42)]. This also works for padding.

Both features are shown below:

#[bitfield(u16)]
#[derive(PartialEq, Eq)]
struct MyBitfield {
    /// Interpreted as 1-bit flag, with custom default
    #[bits(default = true)]
    flag: bool,
    /// Supports any type, with default/to/from expressions (that are const eval)
    /// - into/from call #ty::into_bits/#ty::from_bits if nothing else is specified
    #[bits(13, default = CustomEnum::B, from = CustomEnum::my_from_bits)]
    custom: CustomEnum,
    // Padding with default
    #[bits(2, default = 0b10)]
    __: (),
}

/// A custom enum
#[derive(Debug, PartialEq, Eq)]
#[repr(u16)]
enum CustomEnum {
    A, B, C,
}
impl CustomEnum {
    // This has to be const eval
    const fn into_bits(self) -> u16 {
        self as _
    }
    const fn my_from_bits(value: u16) -> Self {
        match value {
            0 => Self::A,
            1 => Self::B,
            _ => Self::C,
        }
    }
}

// New sets defaults
let val = MyBitfield::new();

assert_eq!(val.flag(), true);
assert_eq!(val.custom(), CustomEnum::B);
assert_eq!(val.0 >> 14, 0b10); // padding
  • 0.5.1 fixes an oversight in the Default implementation