Protocol with multiple Headers #455
-
Hello there, I really love this crate and the idea of declarative parsing. I've already worked with pythons construct library in the past and deku is so much fun to work with. It looks like this: #[derive(DekuRead, DekuWrite, Debug)]
#[deku(id_type = "u16", endian = "big")]
enum Header {
#[deku(id = 0x11)]
Standard { data_len: u16, id: u32 },
#[deku(id = 0x22)]
StandardIndexed { data_len: u16, id: u32, index: u16 },
#[deku(id = 0x33)]
Addressed {
data_len: u16,
id: u32,
src: u64,
dst: u64,
},
#[deku(id = 0x44)]
AddressedIndexed {
data_len: u16,
id: u32,
src: u64,
dst: u64,
index: u16,
},
} This header is then followed by bytes of data specified in the #[pyclass]
#[derive(Debug, DekuRead, DekuWrite)]
struct Message {
header: Header,
#[deku(count = "header.data_len")]
data: Vec<u8>,
} This however doesn't work, which makes sense to me, because how should the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Yep! use deku::prelude::*;
#[derive(Debug, DekuRead, DekuWrite)]
#[deku(endian = "big")]
struct Packet {
id: u16,
data_len: u16,
#[deku(ctx = "*id")]
header: Header,
#[deku(count = "data_len")]
data: Vec<u8>,
}
#[derive(DekuRead, DekuWrite, Debug)]
#[deku(
ctx = "endian: deku::ctx::Endian, data_len: u16",
id = "data_len",
endian = "endian"
)]
enum Header {
#[deku(id = 0x11)]
Standard { id: u32 },
#[deku(id = 0x22)]
StandardIndexed { id: u32, index: u16 },
#[deku(id = 0x33)]
Addressed { id: u32, src: u64, dst: u64 },
#[deku(id = 0x44)]
AddressedIndexed {
id: u32,
src: u64,
dst: u64,
index: u16,
},
}
fn main() {
let bytes = [0x00, 0x11, 0x00, 2, 0x00, 0x00, 0x00, 0xff, 0x01, 0x02];
let p = Packet::from_bytes((&bytes, 0));
dbg!(p);
}
|
Beta Was this translation helpful? Give feedback.
Yep!
ctx
is the way I would do it.