#位字段 # #协议 #lsb #解析器 #位字段

bitwrap_derive_extra

bitwrap宏

5个稳定版本

2.0.6 2022年8月29日
2.0.4 2022年6月20日
2.0.3 2021年11月23日
2.0.2 2021年10月24日

#6 in #lsb

每月下载量 45
用于 bitwrap_extra

MIT 许可证

18KB
415

BitWrap

变更日志

  1. 虚拟字段设置字段 虚拟变量如果设置,则设置self字段可以访问
    #[bitfield(16, name = data_len, value = self.data.len(), pack = LE, unpack = LE)]
    data_len: u16,
    
  2. 默认为be,使pack/uppack支持le配置,()大小端增加配置,默认是大端
    #[bitfield(16, name = data_len, value = self.data.len(), pack = LE, unpack = LE)]
    data_len: u16,
    
  3. 子结构体添加len()函数 嵌套结构体自动增加长度函数
    self.len()
    
  4. 修复测试

docs

BitWrap是一个衍生宏和特质,用于声明具有显式大小(以位为单位)的结构体数据成员。


BitWrapExt特质

特质声明了2个方法

fn pack(&self, dst: &mut [u8]) -> Result<usize, BitWrapError>

pack 方法将结构体字段序列化为 dst 数组

fn unpack(&mut self, src: &[u8]) -> Result<usize, BitWrapError>

unpack 方法从 src 数组反序列化结构体字段

BitWrap宏

use {
    core::convert::{
        TryFrom,
        Infallible,
    },
    std::net::Ipv4Addr,
    bitwrap_extra::{
        BitWrap,
        BitWrapExt,
        BitWrapError,
    },
};

#[derive(Debug, PartialEq, Clone, Copy)]
enum Variant { Value55, ValueAA }

impl Default for Variant {
    fn default() -> Self { Variant::Value55 }
}

impl TryFrom<u8> for Variant {
    type Error = BitWrapError;
    fn try_from(value: u8) -> Result<Self, Self::Error> {
        match value {
            0x55 => Ok(Variant::Value55),
            0xAA => Ok(Variant::ValueAA),
            _ => Err(BitWrapError),
        }
    }
}

impl TryFrom<Variant> for u8 {
    type Error = Infallible;
    fn try_from(value: Variant) -> Result<Self, Self::Error> {
        match value {
            Variant::Value55 => Ok(0x55),
            Variant::ValueAA => Ok(0xAA),
        }
    }
}

#[derive(BitWrap)]
struct Packet {
    // single bit field
    #[bitfield(1)]
    field_1: u8,

    // bit field as boolean. 0 is false, otherwise is true
    #[bitfield(1)]
    field_2: bool,

    // virtual field with option `name`
    // unpack reads bits to the internall variable `_reserved`
    // pack sets 6 bits from defined `value`
    #[bitfield(6, name = _reserved, value = 0b111111)]

    // use TryFrom<u8> for Variant
    #[bitfield(8)]
    variant: Variant,

    // use TryFrom<u32> for Ipv4Addr
    #[bitfield(32)]
    ip: std::net::Ipv4Addr

    // byte array
    #[bitfield]
    mac: [u8; 6],

    // virtual field with optn `name` to define buffer length
    #[bitfield(8, name = data_len, value = self.data.len())]

    // get slice of `data_len` bytes and call BitWrapExt method for Vec<T>
    // where T is u8 or with implemented BitWrapExt + Default traits
    #[bitfield(data_len)]
    data: Vec<u8>,
}

调试

cargo expand --test array > tests/array_expand.rs
cargo expand --example protocol > examples/protocol_expand.rs
cargo expand --example protocol1 > examples/protocol1_expand.rs
cargo expand --example protocol_le > examples/protocol_le_expand.rs
cargo expand --example protocol_data_len > examples/protocol_data_len_expand.rs
cargo expand --example protocol_nested > examples/protocol_nested_expand.rs

依赖关系

~1.5MB
~36K SLoC