Composing structs with top level attributes #567
-
Hi, I'm trying to compose 2 structs where both structs use the DekuRead derive macro and the top level struct has a endian attribute. However when I try to do this I get an error. Here is an example code snippet: use deku::{DekuContainerRead, DekuRead};
#[derive(Debug, PartialEq, Eq, Clone, DekuRead)]
struct Foo {
a: u16,
}
#[derive(Debug, PartialEq, Eq, Clone, DekuRead)]
#[deku(endian = "little")]
struct Bar {
f: Foo,
b: u16,
}
fn main() {
let bs = [0x02, 0x01, 0x01, 0x02];
let (_, b) = Bar::from_bytes((&bs, 0)).unwrap();
println!("{:?}", b);
} The error I get is: It looks like the issue is that the generate impl of DekuReader for Bar calls the generated I tried adding My expectation is that setting Is my expectation correct? and how would I achieve something like this? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi @DevonKS , we have an example of this pattern here: https://docs.rs/deku/latest/deku/attributes/index.html#endian // Note: The endian is passed as a context argument to sub-types
// Example:
#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian")] // context passed from `DekuTest` top-level endian
struct Child {
field_a: u16
}
#[deku(endian = "little")] // top-level, defaults to system endianness
struct DekuTest {
#[deku(endian = "big")] // field-level override
field_be: u16,
field_default: u16, // defaults to top-level
// because a top-level endian is specified,
// it is passed as a context
field_child: Child,
}
let data: &[u8] = &[0xAB, 0xCD, 0xAB, 0xCD, 0xEF, 0xBE];
let value = DekuTest::try_from(data).unwrap();
assert_eq!(
DekuTest {
field_be: 0xABCD,
field_default: 0xCDAB,
field_child: Child { field_a: 0xBEEF }
},
value
);
let value: Vec<u8> = value.try_into().unwrap();
assert_eq!(&*data, value); |
Beta Was this translation helpful? Give feedback.
Hi @DevonKS , we have an example of this pattern here: https://docs.rs/deku/latest/deku/attributes/index.html#endian