#binary-data #data-stream #pack-unpack #complex

无std binmarshal

将结构体和枚举打包和解包到二进制数据流中

33个版本 (11个稳定版)

1.1.7 2024年6月6日
1.1.6 2024年1月5日
0.2.9 2023年12月30日
0.1.12 2023年11月26日

#1 in #pack-unpack

每月22次下载
用于 3 个crate(2个直接使用)

MIT 许可证

41KB
929

Binmarshal

crates.io Documentation

将结构体和枚举打包和解包到二进制数据流中。

添加到您的项目中

cargo add binmarshal

打包结构体和枚举

use binmarshal::*;

#[derive(Debug, Clone, BinMarshal)]
#[marshal(tag_type = u8)]
enum MyEnum {
  #[marshal(tag = "0")]
  Variant1,
  #[marshal(tag = "1")]
  Variant2 {
    #[marshal(bits = 4)]
    a: u8,
    #[marshal(align = 1)]
    b: u16,
    c: LengthTaggedVec<u8, i32>
  }
}

fn main() {
  let v = MyEnum::Variant2 {
    a: 13,
    b: 5192,
    c: LengthTaggedVec::new(vec![ -12, -242, 12034 ])
  };

  // Packing
  let mut bytes = [0u8; 256];
  let mut writer = BufferBitWriter::new(&mut bytes);
  v.write(&mut writer, ());
  let slice = writer.slice();   // Gives you a &[u8] reference of the appropriate length, as a subset of "bytes"

  // Unpacking
  let v = MyEnum::read(&mut BitView::new(slice), ()).unwrap();
}

使用上下文

上下文允许您在结构体和枚举之间传递变量,主要用于标记枚举。如果您使用带有上下文的标记枚举,必须在写入之前调用 .update()

use binmarshal::*;

#[derive(Clone)]
struct MyContext {
  tag: u8
}

#[derive(Debug, Clone, BinMarshal)]
#[marshal(ctx = MyContext, tag_type = u8, tag = "ctx.tag")]
enum MyEnum {
  #[marshal(tag = "1")]
  Variant1,
  #[marshal(tag = "2")]
  Variant2,
}

#[derive(Debug, Clone, BinMarshal)]
struct MyStruct {
  variant: u8,
  #[marshal(ctx = "construct", ctx_member(field = "tag", member = "variant"))]
  inner: MyEnum
}

示例

更复杂的示例请参阅 示例

依赖项

~0.9–1.6MB
~35K SLoC