7 个版本 (4 个重大更新)

0.5.1 2020年2月19日
0.5.0 2020年2月19日
0.4.0 2020年2月16日
0.3.0 2020年2月11日
0.1.1 2020年2月10日

#1164 in 开发工具

每月下载 28 次

MIT/Apache

17KB
272

位字段的宏定义。

该软件包包含 bitfield! 宏和 BitEnum derive。

bitfield! 用于生成位字段的 getter 和 setter 方法。 BitEnum 允许枚举用作字段值。

示例

use bitbash::{bitfield, BitEnum};

bitfield! {
    #[derive(Copy, Clone, PartialEq, Eq)]
    pub struct Foo(u16);

    pub new(bar);
    derive_debug;

    pub field bar: Bar = [0..3];
    pub field baz: usize = [3..7] ~ [8..12];
    pub field quux: bool = [7];
}

#[derive(BitEnum, Copy, Clone, PartialEq, Eq, Debug)]
pub enum Bar {
    A = 0b101,
    B = 0b010,
}

fn main() {
    let mut foo = Foo::new(Bar::A).with_baz(0xcd);
    foo.set_quux(true);
    assert_eq!(foo.bar(), Bar::A);
    assert_eq!(foo.baz(), 0xcd);
    assert!(foo.quux());
    assert_eq!(foo.0, ((Bar::A as u16) << 0) | (0xd << 3) | (0xc << 8) | (1 << 7));
}

bitfield!

支持的 struct

bitfield! 宏支持三种 struct:无符号整数的元组 struct、无符号整数数组的元组 struct 和常规 struct。

bitfield! {
    struct Foo(u8);

    field a: bool = [7];
}

bitfield! {
    struct Bar([u32; 2]);

    field a: bool = 0[7];
    field b: bool = 1[7];
}

bitfield! {
    struct Baz {
        _padding: [u32; 1],
        apple: u32,
        banana: u32,
    }

    field a: bool = apple[7];
}

常规 struct 可能包含非无符号整数类型,但是它们不能通过 field 来引用。

(pub) field

field 语句定义值存储在哪些位上。字段可以引用单个位、位范围、位组合或值中的位到位字段的映射。

bitfield! {
    struct Foo([u32; 2]);

    field single: bool = 0[0];
    field range: u8 = 0[0..8];
    field concatenation: u16 = 0[0..8] ~ 1[8..16];
    field mapping: u32 {
        [8..16] => 1[8..16],
        [31] => 0[31],
    }
}

默认情况下,为每个字段生成三种方法:getter、setter 和 builder

fn field_name(&self) -> Value;
fn set_field_name(&mut self, value: Value);
fn with_field_name(self, value: Value) -> Self;

要仅生成 getter,请使用 #[ro] 属性。要将 pub 字段 的 setter 和 builder 设置为私有,请使用 #[private_write] 属性。

当读取字段时,其位必须是值的有效表示。当写入字段时,只能设置值中由字段引用的位。如果不满足这些要求,将发生 panic。

引用不存在的位将导致编译时错误或运行时错误,具体取决于是否生成了 const fn 代码。

值构建完全在安全代码中完成。此外,这个crate中的宏不会生成不安全代码。

(pub) new()

当指定 new() 语句时,会生成一个 fn new() 方法,该方法将位字段初始化为零。对于零不是有效表示的字段,可以将它们作为参数传递给 new() 语句以生成一个方法,该方法将它们的初始值作为参数

bitfield! {
    struct Foo(u32);

    new(a);

    field a: Bar = [0..3];
}

#[derive(BitEnum)]
enum Bar {
    A = 0b101,
    B = 0b010,
}

fn main() {
    let _ = Foo::new(Bar::A);
}

当位字段构建完成后,new 方法会读取所有字段以确保位字段中没有无效的表示。可以通过使用 #[disable_check] 属性来禁用此行为。

new() 不支持包含非(无符号整数的数组)类型的结构体。

derive_debug

derive_debug 语句实现了位字段的 core::fmt::Debug。底层表示不会打印。

const fn

要生成 const fn 方法,请使用带有 "const" 特性的 bitbash crate 进行构建。或者,使用 bitflags_const! 宏。

需要夜间编译器,并且必须启用 #![feature(const_fn, const_panic, const_if_match, const_mut_refs)] 特性。

ConvertRepr trait

位字段值必须实现 ConvertRepr trait。它对所有无符号整数类型以及从 BitEnum 继承的类型进行了实现。

在非 const fn 位字段中,使用 try_from_reprinto_repr 方法。在您的类型上实现 const_try_from_reprconst_into_repr 以在 const fn 位字段中也要使用它们。

BitEnum derive

BitEnum derive 为C样式的枚举实现了 ConvertRepr

继承自 BitEnum 的枚举可以用于 const fn 和非 const fn 位字段。

依赖关系

~1.5MB
~35K SLoC