bin-proto: A new crate for bit-level binary protocols

55 points wojtek-graj

Rust has great support for ser/de to a huge variety of formats, but lacked a library for parsing arbitrary binary data with bit-level precision (e.g. IP headers), and crates for ser/de with byte-level precision either:

  • have their own custom format (e.g. bincode, postcard)
  • are old and unmaintained (e.g. protocol)

Enter bin-proto, a crate I wrote (forked from the protocol crate), that can do exactly this, and more. With a derive macro you can make a struct encode-able and decode-able from a binary format that you have control over. Obviously the alternative is a custom parser (probably using nom), but if ease-of-use is more important than squeezing the most value out of every CPU cycle, I think this crate could be very useful.

#[derive(Debug, Protocol, PartialEq)]
struct S {
    #[protocol(bits = 1)]
    bitflag: bool,
    #[protocol(bits = 7)]
    field: u8,
    // Don't include length prefix
    #[protocol(flexible_array_member)]
    data: Vec<u8>,
}

assert_eq!(
    S::from_bytes(&[
        0b1000_0000 // bitflag
       | 0b001_0010, // field
       0x01, 0x02, 0x03 // data
    ], &bin_proto::Settings::default()).unwrap(),
    S {
        bitflag: true,
\tfield: 18,
\tdata: vec![1, 2, 3]
    }
);

I'd love to hear what everybody thinks about this - feedback is much appreciated. Check it out here, and on crates.io: https://github.com/wojciech-graj/bin-proto