因为
工作涉及的编解码内容较多,且字段灵活,目前没有找到能适配的lib能可以用的。最早用c语言可以使用bit field,还能方便点,但是遇到Optional字段或者Dynamic Length字段一样需要手写代码。
自从使用Rust后,都是手写编解码,每个字节&
,>>
,<<
,~
,|
很累,特别是遇到不对齐的field时候更头疼。
所以
打算自己造个轮子,使用proc_macro
为什么不用bincode? 因为bincode编码方式不能自定义,比如对于vec字段,前8个字节是固定vec数量大小的。
目标
灵活定义字段
#[derive(BinEncodeBe)]
pub struct TsPack {
// 默认bit size等于字段类型
pub sync_code: u8,
// bool类型的bit size 总是等于1
pub translation_error: bool,
pub first_payload: bool,
pub high_priority: bool,
// 可自定义数值类型的bit 大小
#[bin(bits(13))]
pub pid: u16,
pub first: bool,
pub last: bool,
// 可以使用skip属性定义保留bit位
#[bin(skip(2))]
#[bin(bits(4))]
pub cnt: i8,
// 可以使用Option、Vec类型包裹
// None时不编码
// 当first_payload=true时才会解码该字段,否则设置未None
#[bin(is_some(first_payload))]
pub option: Option<u128>,
// 可以嵌套复合类型
// 解码时根据count进行匹配vec items数量
#[bin(count(cnt as usize))]
pub vec: Vec<TsPack>,
}
目前
以前已经实现过一次,但是性能堪忧。 目前已经重写了编码,解码还在进行中。所以是否有人对这个库感兴趣?
项目地址
https://github.com/ywzjackal/bin_codec.rs crates: bin_codec, bin_codec_derive
1
共 3 条评论, 1 页
评论区
写评论Hello, 项目发布在https://github.com/ywzjackal/bin_codec.rs。由于支持灵活的bit定义,所以性能比较差,等const fn稳定后应该会很方便进行优化。 对以下内容的回复:
关注
use bin_codec::*; use bin_codec_derive2::{BinEncodeBe}; #[derive(BinEncodeBe)] pub struct TsPack { // 00 : 0 pub sync_code: u8, // 01 : 7 pub translation_error: bool, // 01 : 6 pub first_payload: bool, // 01 : 5 pub high_priority: bool, // 01 : 4 #[bin(bits(13))] pub pid: u16, pub first: bool, pub last: bool, #[bin(skip(2))] #[bin(bits(4))] pub seq: i8, } #[test] fn test_ts_encode() { let ts = TsPack { sync_code: 0x47, translation_error: false, first_payload: true, high_priority: false, pid: 0x1abc, first: true, last: false, seq: 0xA, }; let mut target = [0u8; 4]; ts.encode(&mut target, &mut Context::<()>::default()); let shouldbe = [0x47, 0b0100_0000 | 0x1A, 0xBC, 0b1000_0000 | 0xA]; assert_eq!(target, shouldbe, "\r\n{:02X?} \r\n {:02X?}", target, shouldbe); assert_eq!(4 * 8, ts.bits()); }