sharksforarms / deku

Declarative binary reading and writing: bit-level, symmetric, serialization/deserialization

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Working with elements of Vec<StructUsingDeku> to get sum of their byte-sizes

sempervictus opened this issue · comments

When using complex structures such as:

pub(super) struct Message {
    pub(super) hdr: MsgHeader,
    #[deku(count = "hdr.service_count")]
    pub(super) svcs: Vec<Svc>,
}

getting update to work becomes non-trivial since there's no good way to count up the sizes of those Svc structs given that they are

pub(super) struct Svc {
    pub(super) hdr: SvcHeader,
    #[deku(ctx = "*hdr")]
    pub(super) svc: SvcBody,
}
pub enum AnoSvcBody {
    #[deku(id = "0x0001")]
    FIRST {
        version: UbString,
...

themselves nested structures including typed enums based on a value in the Svc hdr struct.
Attempting to

    pub fn update(&mut self) -> Result<(), DekuError> {
        let v: Vec<Vec<u8>> = self.svcs.iter()
            .map(|s| s.try_into()?)
            .collect();
        self.hdr.length = v.iter().map(|s| s.len()).sum();
        Ok(())
    }

causes

the trait `From<&Svc>` is not implemented for `Vec<u8>`

as do attempts to deref() in the map. Similarly to_bytes() is not found on &Svc 🤦

Ideally references would accept trait methods the same way as the owned structs, otherwise are there any macros or other sugar available to access these deeply nested members and pull the byte-sizes for summation?

Come to think of it... deku::size_of(struct) would be nice for the nested complexity of enums structured this way.

to_bytes() is only generated by types not using ctx: https://docs.rs/deku/latest/deku/trait.DekuContainerRead.html

You could use https://docs.rs/deku/latest/deku/attributes/index.html#ctx_default, if the ctx wouldn't affect your .len.

Const size generation was also asked for here: #307

Thanks for the pointers. Unfortunately ctx is how the type is passed from headed to typed-enum-body, but I'll see if I can make the default one work. Happen to have any dirty tricks in your code bag to get sizes for those lower-level child structs/enums or getting them to marshal into bytes somehow? Try into should work but being behind a reference breaks that as well.

@sempervictus I know it's been a while, but providing a full code example (even if it's failing) will make it easier for us to try and find a solution, it's hard/wasteful for us to make assumptions on your intention and binary format