Deku provides bit level serialization/deserialization proc-macros for structs
Under the hood, it uses bitvec as the "Reader" and “Writer”
toml
[dependencies]
deku = "0.1"
```rust use deku::prelude::*; use std::convert::TryFrom;
/// DekuTest Struct // 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | fielda | fieldb |c| field_d | e | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //
// #[deku(endian = "little")] // By default it uses the system endianess, but can be overwritten struct DekuTest { fielda: u8, #[deku(bits = "7")] fieldb: u8, #[deku(bits = "1")] fieldc: u8, #[deku(endian = "big")] fieldd: u16, #[deku(bits = "2")] field_e: u8, }
fn main() { let testdata: &[u8] = [0xAB, 0b10100101, 0xAB, 0xCD, 0b11000000].asref();
let test_deku = DekuTest::try_from(test_data).unwrap();
assert_eq!(
test_deku,
DekuTest {
field_a: 0xAB,
field_b: 0b0_1010010,
field_c: 0b0000000_1,
field_d: 0xCDAB,
field_e: 0b0000_0011,
}
);
let test_deku: Vec<u8> = test_deku.into();
assert_eq!(test_data.to_vec(), test_deku);
} ```