Expand description
bitstructs is a library for defining type-safe bitfield structures
that can be used in both std and no_std environments.
The library provides three macros, bitstruct_cow, bitstruct_owned,
and bitstruct_small, for generating BitStruct. It also includes
the bitstruct_field_enum macro for safely generating enum types
for fields within BitStruct. Only bitstruct_cow is not supported
in no_std environments because it relies on std::borrow::Cow.
bitstructs是一个可同时用于std和no_std 环境,定义类型安全的位域结构体的库。
该库提供了bitstruct_cow、bitstruct_owned、bitstruct_small三个宏,
用于生成BitStruct。以及bitstruct_field_enum宏,用于安全的生成BitStruct中字段枚举类型。
其中只有bitstruct_cow 因为需要使用std::borrow::Cow ,所以不支持 no_std 环境。
§Defining BitStruct
The usage of the three macros, bitstruct_cow, bitstruct_owned, and bitstruct_small, is similar.
The syntax is similar to Rust’s struct definition, except that
a number is used after the field name to indicate the bit width
instead of the type. You can optionally use => to specify
the corresponding enum type for the field. The field’s enum type
can be declared inline or referenced from an external definition.
bitstruct_cow、bitstruct_owned、bitstruct_small三个宏的使用方法类似。
语法类似rust的结构体定义,只是在字段名后使用数字表示位宽而非类型,
然后可以选择的使用=>设置字段的对应的枚举类型。字段枚举类型可以
使用内联枚举声明,也可以使用外部定义的枚举类型。
use bitstructs::{bitstruct_owned};
bitstruct_owned! {
#[derive(Clone, Debug, PartialEq)]
pub struct Foo {
a: 1,
b: 2,
c: 2 =>
pub enum C {
C0 = 0,
C1 = 1,
},
}
}
let mut value = Foo::new();
assert_eq!(value.as_bytes(), vec![0b0000_0000]);
value.set_a(true);
unsafe { value.set_b(1) };
value.set_c(C::C1);
assert_eq!(value.as_bytes(), vec![0b0000_1011]);By default, the library uses LSB0 and little-endian mode.
To use MSB0 and big-endian mode, add #[bitstruct_repr(MSB0)] to the struct.
默认情况下,采取的是LSB0和小端模式。如果要使用MSB0和大端模式,
可以在结构体上添加中添加#[bitstruct_repr(MSB0)]。
use bitstructs::{bitstruct_owned};
/// MSB0 and big-endian mode
/// MSB0和大端模式
bitstruct_owned! {
#[derive(Clone, Debug, PartialEq)]
#[bitstruct_repr(MSB0)]
pub struct Foo {
a: 1,
b: 2,
c: 2 =>
pub enum C {
C0 = 0,
C1 = 1,
},
}
}
let mut value = Foo::new();
assert_eq!(value.as_bytes(), vec![0b0000_0000]);
value.set_a(true);
unsafe { value.set_b(1) };
value.set_c(C::C1);
assert_eq!(value.as_bytes(), vec![0b1010_1000]);The bitstruct_owned macro generates the following methods:
fn new() -> Self: Creates a newBitStruct.fn bytes_len() -> usize: Gets the number of bytes occupied by theBitStruct.fn from_bytes(bytes: &[u8]) -> Result<Self, BitStructError>: Creates aBitStructfrom a byte array.fn as_bytes(&self) -> &[u8]: Gets an immutable reference to the byte array of theBitStruct.fn as_bytes_mut(&mut self) -> &mut [u8]: Gets a mutable reference to the byte array of theBitStruct.- Methods for reading and setting each field. For fields without a specified enum type, the type will be chosen from
bool,u8,u16,u32, oru128. Fields exceeding 128 bits will cause a compilation failure. For example,fn b(&self) -> u8andunsafe fn set_b(&mut self, value: u8),fn c(&self) -> Candfn set_c(&mut self, value: C).
The usage of bitstruct_cow is the same as bitstruct_owned,
but the generated BitStruct uses Cow internally. Additionally,
as_bytes and as_bytes_mut are replaced with to_bytes and to_bytes_mut.
The usage of bitstruct_small is similar to bitstruct_owned,
but it restricts the size of BitStruct to a maximum of 128 bits.
It does not support #[bitstruct_repr(MSB0)] but allows #[bitstruct_repr(u8)]
to explicitly specify the internal storage type of BitStruct.
bitstruct_owned宏会生成以下方法:
fn new() -> Self:创建一个新的BitStruct。fn bytes_len() -> usize:获取BitStruct占用的字节数。fn from_bytes(bytes: &[u8]) -> Result<Self, BitStructError>:从字节数组中创建BitStruct。fn as_bytes(&self) -> &[u8]:获取BitStruct的字节数组引用。fn as_bytes_mut(&mut self) -> &mut [u8]:获取BitStruct的字节数组可变引用。- 各个字段的读取和设置方法,对于没有指定枚举类型的字段,类型将会使用
bool,u8,u16,u32,u128中选择。超过128位,将会编译失败。 例如fn b(&self) -> u8和unsafe fn set_b(&mut self, value: u8),fn c(&self) -> C和fn set_c(&mut self, value: C)。
bitstruct_cow的使用和bitstruct_owned相同,只是生成的BitStruct内部是Cow类型,
以及将as_bytes,as_bytes_mut换成了to_bytes,to_bytes_mut。
bitstruct_small的使用和bitstruct_owned类似。但是限制了BitStruct的大小,最大为128位。
以及不支持使用#[bitstruct_repr(MSB0)],但是支持#[bitstruct_repr(u8)]去显示指定BitStruct内部的实际存储类型。
use bitstructs::{bitstruct_small};
/// Specifying the storage type as u32
/// 指定存储类型为u32
bitstruct_small! {
#[derive(Clone, Debug, PartialEq)]
#[bitstruct_repr(u32)]
pub struct Foo {
a: 1,
b: 2,
reserved: 2,
c: 2 =>
#[derive(Debug, PartialEq, Eq)]
pub enum C {
C0 = 0,
C1 = 1,
},
}
}
let value: u32 = 0b0100_10_1;
let value = Foo::from_value(value);
assert_eq!(value.a(), true);
assert_eq!(value.b(), 2);
assert_eq!(value.c(), C::C1);§Defining Enum Types
In addition to defining enum types within the bitstruct_owned, bitstruct_cow,
and bitstruct_small macros as shown in the example above, enum types can also
be defined externally. Unlike inline enums, externally defined enum types can be reused. Here is a simple example:
除了像上面例子那样,在bitstruct_owned、bitstruct_cow、bitstruct_small宏中定义枚举类型,还可以在外部定义枚举类型。
在外部定义的枚举类型,不同于内联枚举,可以重复使用。下面是一个简单的例子:
use bitstructs::{bitstruct_field_enum, bitstruct_owned};
/// This is an enum type suitable for 2 bits
/// 这是一个适用于 2 bit 的枚举类型
#[bitstruct_field_enum(2)]
pub enum TwoBitEnum {
Zero = 0,
One = 1,
Two = 2,
Three = 3,
}
bitstruct_owned! {
pub struct Foo {
a: 4,
b: 2 => TwoBitEnum,
c: 2 => TwoBitEnum,
}
}If the variants in the enum type do not cover all possible values,
variants with the prefix __Reserved will be automatically added.
This also applies to inline enum types.
如果枚举类型中的变体(variants)没有覆盖所有可能的取值,
会自动添加前缀为 __Reserved 的变体。这同样适用于内联枚举类型。
use bitstructs::{bitstruct_field_enum,bitstruct_owned};
#[bitstruct_field_enum(2)]
pub enum TwoBitEnum {
Zero = 0,
Two = 2,
}
bitstruct_owned! {
pub struct Foo {
a: 4,
b: 2 =>
enum B {
Foo = 2,
Bar = 3,
},
}
}The code above is equivalent to:
use bitstructs::{bitstruct_field_enum,bitstruct_owned};
#[bitstruct_field_enum(2)]
pub enum TwoBitEnum {
Zero = 0,
Two = 2,
__Reserved1 = 1,
__Reserved3 = 3,
}
bitstruct_owned! {
pub struct Foo {
a: 4,
b: 2 =>
enum B {
Foo = 2,
Bar = 3,
__Reserved0 = 0,
__Reserved1 = 1,
},
}
}§Confusing Error Messages
If the bit width of the enum type does not match the bit width of the field
in BitStruct, compilation will fail. However, since the current check
for non-inline enum types uses const to trigger a compilation error through overflow,
the error message may not be very friendly when the bit widths do not match.
如果枚举类型的位宽与 BitStruct 中字段的位宽不匹配,编译将会失败。
然而,由于当前对非内联枚举类型的检查是通过使用 const 来触发编译错误(利用溢出),
因此当位宽不匹配时,错误信息不够友好。
use bitstructs::{bitstruct_field_enum,bitstruct_owned};
#[bitstruct_field_enum(2)]
pub enum TwoBitEnum {
Zero = 0,
One = 1,
Two = 2,
Three = 3,
}
bitstruct_owned! {
pub struct Foo {
a: 4,
b: 3 => TwoBitEnum,
}
}The code above will fail to compile with an error message similar to:
error[E0080]: evaluation of constant value failed
--> bitstructs/src/main.rs:9:1
|
9 | / bitstruct_owned! {
10 | | pub struct Foo {
11 | | a: 4,
12 | | b: 3 => TwoBitEnum,
13 | | }
14 | | }
| |_^ attempt to compute `0_u32 - u32::MAX`, which would overflowDeclaring inline enum types is checked during macro expansion, which results in more friendly error messages.
use bitstructs::{bitstruct_small};
bitstruct_small! {
pub struct Foo {
a: 4,
b: 2 =>
enum B {
Zero = 0,
One = 1,
Two = 2,
Three = 3,
Four = 4
},
}
}The code above will fail to compile with an error message similar to:
error: enum type variant count must be less than or equal to 2^2
--> bitstructs/src/main.rs:5:22
|
6 | enum B {
| ^Macros§
- bitstruct_
cow - Use
Cowto implementBitStruct. 使用写时复制的BitStruct实现。 - bitstruct_
owned - Copy the byte data directly, the
BitStructimplementation with ownership. 直接复制字节数据,拥有所有权的BitStruct实现。 - bitstruct_
small - Suitable for small data structure
BitStructimplementation. 适用于小型数据结构的BitStruct实现。
Traits§
- Bitstruct
From Value - A trait that must be implemented for non-inline field enum types. 非内联的字段枚举类型必须实现的trait。
- Bitstruct
ToValue - A trait that must be implemented for non-inline field enum types. 非内联的字段枚举类型必须实现的trait。
Attribute Macros§
- bitstruct_
field_ enum - Used to declare the enumeration type of the field. 用于声明字段的枚举类型。
- bitstruct_
repr - Used to declare the representation of
BitStruct’s store_type or bit_numbering. 用于描述BitStruct的store_type或bit_numbering.