#位字段 # #bitflags #位字段 #位int

无需 std mvbitfield

生成与位对齐字段一起工作的类型

4 个版本 (2 个破坏性更新)

0.2.0 2023年5月29日
0.1.1 2023年5月12日
0.1.0 2023年5月12日
0.0.0 2023年5月7日

1875数据结构

每月下载 48

MIT 许可证

45KB
420

mvbitfield

crates.io docs.rs CI Status

Rust 的位字段库。

mvbitfield 生成用于处理位对齐字段的类型。

位字段结构体大致与 C/C++ 中的位字段成员的结构体具有相同的使用场景,并且是

  • 端序无关的,在整数内部而不是在字节或数组元素之间打包字段。
  • 灵活且类型安全,具有可选的用户定义的字段访问器类型。
  • 始终谨慎地适合用于 FFI 和内存映射 I/O。

位字段枚举是单元 Rust 枚举,具有声明的位宽度,提供安全且零成本的整数类型转换,并可作为位字段结构体中的访问器使用。

演示

// Recommended, but not required. The mvbitfield prelude includes
// the bitint prelude.
use mvbitfield::prelude::*;

bitfield! {
    #[lsb_first]               // Field packing order.
    #[derive(PartialOrd, Ord)] // Other attributes pass through.
    pub struct MyBitfieldStruct: 32 {
        // The lowest three bits with public bitint::U3 accessors.
        pub some_number: 3,

        // The next eight bits with public bitint::U8 accessors.
        pub another_number: 8,

        // No accessors for field names starting with _.
        _padding: 2,

        // Private bitint::U11 accessors.
        internal_number: 11,

        // Skip unused bits, in this case five bits.
        ..,

        // The two next-to-most significant bits with public
        // MyBitfieldEnum accessors.
        pub an_enum: 2 as MyBitfieldEnum,

        // Private bool accessors.
        high_bit_flag: 1 as bool,
    }

    pub enum MyBitfieldEnum: 2 {
        // Declare up to 2^width unit variants with optional
        // explicit discriminants.
        Three = 3,
        Zero = 0,
        One,

        // Generates `Unused2` to complete the enum.
        ..
    }
}

#[bitint_literals]
fn main() {
    // Use generated with_* methods to build bitfield structs.
    let x = MyBitfieldStruct::zero()
        .with_some_number(6_U3)
        .with_another_number(0xa5_U8)
        .with_internal_number(1025_U11)
        .with_an_enum(MyBitfieldEnum::One)
        .with_high_bit_flag(true);

    // Default accessors return bitints.
    assert_eq!(x.some_number(), 6_U3);
    assert_eq!(x.some_number().to_primitive(), 6);
    assert_eq!(x.another_number(), 0xa5_U8);
    assert_eq!(x.another_number().to_primitive(), 0xa5);
    assert_eq!(x.internal_number(), 1025_U11);
    assert_eq!(x.internal_number().to_primitive(), 1025);

    // Custom accessors return the chosen type, which must have Into
    // conversions to and from the default accessor bitint.
    assert_eq!(x.an_enum(), MyBitfieldEnum::One);
    assert_eq!(x.high_bit_flag(), true);

    // Zero-cost conversions to and from bitints and to primitive.
    // For bitfield structs:
    assert_eq!(
        x.to_bitint(),
        0b1_01_00000_10000000001_00_10100101_110_U32,
    );
    assert_eq!(
        x.to_primitive(),
        0b1_01_00000_10000000001_00_10100101_110,
    );
    assert_eq!(x, MyBitfieldStruct::from_bitint(0xa080252e_U32));
    // For bitfield enums:
    assert_eq!(MyBitfieldEnum::One.to_bitint(), 1_U2);
    assert_eq!(MyBitfieldEnum::One.to_primitive(), 1);
    assert_eq!(
        MyBitfieldEnum::One,
        MyBitfieldEnum::from_bitint(1_U2),
    );

    // Zero-cost conversion from primitive, only for primitive-sized
    // bitfield structs and enums.
    assert_eq!(x, MyBitfieldStruct::from_primitive(0xa080252e));
    bitfield! { enum MyU8Enum: 8 { X = 192, .. } }
    assert_eq!(MyU8Enum::X, MyU8Enum::from_primitive(192));

    // Bitfield enums optionally generate placeholder variants for
    // unused discriminants with `..`. The name is always "Unused"
    // followed by the discriminant value in base 10.
    assert_eq!(MyBitfieldEnum::Unused2.to_bitint(), 2_U2);
    assert_eq!(
        MyBitfieldEnum::Unused2,
        MyBitfieldEnum::from_bitint(2_U2),
    );
}

依赖关系

~0.6–1.1MB
~24K SLoC