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 or supported primitive type, such as bool
,
u8
, u16
, u32
, u64
, and u128
, for the field. If not specified,
the smallest primitive type that can contain the field will be chosen.
The field’s enum type can be declared inline or referenced from an external definition.
Note: =>
specifies the type used for reading and writing the field,
and does not affect the storage type of the field.
bitstruct_cow
、bitstruct_owned
、bitstruct_small
三个宏的使用方法类似。
语法类似rust的结构体定义,只是在字段名后使用数字表示位宽而非类型,
然后可以选择的使用=>
设置字段的对应的枚举类型或支持的基本类型,如bool
,u8
,u16
,u32
,u64
,u128
,
如果没有指定,默认选择可容纳字段的最小基本类型。字段枚举类型可以使用内联枚举声明,
也可以使用外部定义的枚举类型。
注意:=>
指定的类型只是用于字段的读取和写入的类型,不会影响字段的存储类型。
use bitstructs::{bitstruct_owned};
bitstruct_owned! {
#[derive(Clone, Debug, PartialEq)]
pub struct Foo {
a: 1 => bool,
b: 2, // equivalent to `b: 2 => u8`
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 => bool,
b: 2, // equivalent to `b: 2 => u8`
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 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
.
The methods generated by bitstruct_owned, bitstruct_cow, and bitstruct_small can refer to the examples in examples.
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
内部的实际存储类型。
bitstruct_owned
、bitstruct_cow
、bitstruct_small
生成的方法可参考examples
中的例子。
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 => bool,
b: 2 => u32,
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(), 2u32);
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)]
#[derive(Debug)]
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.
Note: #[bitstruct_field_enum(2)]
should be placed above #[derive(Debug)]
,
otherwise Debug
will not recognize the automatically completed variants.
如果枚举类型中的变体(variants)没有覆盖所有可能的取值,
会自动添加前缀为 __Reserved
的变体。这同样适用于内联枚举类型。
注意:#[#[bitstruct_field_enum(2)]
应该在#[derive(Debug)]
上方,否则Debug
不会识别到自动补全的变体。
use bitstructs::{bitstruct_field_enum,bitstruct_owned};
#[bitstruct_field_enum(2)]
#[derive(Debug)]
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)]
#[derive(Debug)]
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 overflow
Declaring 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 {
| ^
Modules§
- examples
- Examples of using
bitstructs
in macro expansion, used to better demonstrate the methods generated by the macro. 使用宏定义的bitstructs
例子,用于更好的展示宏的展开后产生的方法。
Macros§
- bitstruct_
cow - Use
Cow
to implementBitStruct
. 使用写时复制的BitStruct
实现。 - bitstruct_
owned - Copy the byte data directly, the
BitStruct
implementation with ownership. 直接复制字节数据,拥有所有权的BitStruct
实现。 - bitstruct_
small - Suitable for small data structure
BitStruct
implementation. 适用于小型数据结构的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.