macro_rules! fields {
(
$(
$buffer_type:path [$raw_data:ident] {
$(
$field:tt [$position_start:literal $(..= $position_end:literal)? , $rw:tt, $value_type:tt $(<$generic:tt>)?] $({
$(input_converter:$input_converter:expr;)?
$(output_converter:$output_converter:expr)?
})?
),+ $(,)?
}
)+
) => { ... };
(__ops: ro, $buffer_type:ty, $value_type:tt, $field:ident, $raw_data:ident, $position_start:literal $(..= $position_end:literal)?
$(output_converter:$output_converter:expr)?
) => { ... };
(__ops: rw, $buffer_type:path, $value_type:tt, $field:ident, $raw_data:ident, $position_start:literal $(..= $position_end:literal)?
$(input_converter:$input_converter:expr;)?
$(output_converter:$output_converter:expr;)?
) => { ... };
(__output_converter: $var:ident, bool) => { ... };
(__output_converter: $var:ident, $value_type:tt) => { ... };
($__converter:tt: $var:ident, $value_type:tt) => { ... };
($__converter:tt: $var:ident, $value_type:tt, $converter:expr) => { ... };
}
Expand description
用于为含有 bit field 的结构体中的 bit 字段实现
Field
、FieldReader
、FieldWriter
接口。
具体用法看示例:
use bits::field::BufferWriter;
use bits::field::BufferReader;
use bits::IntoBits;
use bits::BitsOps;
pub struct FoolData {
data: u32,
data1: u32,
}
impl BufferWriter for FoolData{}
impl BufferReader for FoolData{}
// bit 字段 1,其余类推
pub struct Flag1;
pub struct Flag2;
pub struct Flag3;
pub struct Flag4;
pub struct Flag5;
pub struct Flag6;
bits::fields! {
FoolData [data] {
Flag1 [0..=3, rw, u32],
Flag2 [4..=5, rw, u32],
Flag3 [6, ro, bool],
Flag4 [7, rw, bool],
Flag5 [8..=9, rw, bool] {
input_converter: |x| match x {
true => 0x1,
_ => 0x0
};
output_converter: |x| match x {
0x1 => true,
_ => false
}
}
}
FoolData [data1] {
Flag6 [0..=3, rw, u32]
}
}
let mut fool = FoolData {data:0x0, data1: 0x0};
fool.write::<Flag1>(0xf);
assert_eq!(fool.data, 0xf);
fool.write::<Flag2>(0x3);
assert_eq!(fool.data, 0b0011_1111);
// error: the trait `FieldWriter<FoolData>` is not implemented for `Flag3`
// fool.write::<Flag3>(true); // Flag3 is not writeable
fool.write::<Flag4>(true);
assert_eq!(fool.data, 0b1011_1111);
let flag3 = fool.read::<Flag3>();
assert_eq!(flag3, false);
let flag4 = fool.read::<Flag4>();
assert_eq!(flag4, true);
fool.data = fool.data.bits(8..=9).write(0x2); // set fool.data bits 8..=9 to 0x2
assert_eq!(false, fool.read::<Flag5>()); // bits: 8..=9 equal to 0x2 which is false
fool.write::<Flag5>(true);
assert_eq!(0b01, fool.data.bits(8..=9).read());
值得注意的是将字段结构体定义留给程序员自行定义, 这样可以避免在同一个命名空间内,通过宏为不同的结构体定义相同的字段时, 造成重定义。