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 字段实现 FieldFieldReaderFieldWriter 接口。 具体用法看示例:

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());

值得注意的是将字段结构体定义留给程序员自行定义, 这样可以避免在同一个命名空间内,通过宏为不同的结构体定义相同的字段时, 造成重定义。