Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing a struct in ctx creates opaque error #408

Open
sempervictus opened this issue Jan 20, 2024 · 7 comments
Open

Passing a struct in ctx creates opaque error #408

sempervictus opened this issue Jan 20, 2024 · 7 comments

Comments

@sempervictus
Copy link

Using non-adjacent fields to determine and then read enum types per https://github.com/sharksforarms/deku/blob/master/examples/enums.rs appears to get convoluted when endianness and identifiers are in the context. Specifically:

#[deku_derive(DekuRead, DekuWrite)]
#[derive(Debug, PartialEq)]
#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian")]
pub(super) struct Svc {
    pub(super) hdr: SvcHeader,
    #[deku(ctx = "*hdr")]
    pub(super) svc: SvcBody
}
#[deku_derive(DekuRead, DekuWrite)]
#[derive(Debug, PartialEq)]
#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian")]
pub(super) struct SvcHeader {
    pub(super) svc_type: u16,
    pub(super) pkts: u16,
    #[deku(assert = "*tail == 0")]
    pub(super) tail: u32,
}
#[deku_derive(DekuRead, DekuWrite)]
#[derive(Debug, PartialEq)]
#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian, hdr: SvcHeader", id = "hdr.svc_type")]
pub enum SvcBody {
    #[deku(id = "0x0001")]
    FIRST {
...

doesn't compile due to:

151 | #[deku_derive(DekuRead, DekuWrite)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: message: called `Result::unwrap()` on an `Err` value: Error("expected `,`")

being thrown from the SvcBody enum

@sempervictus
Copy link
Author

sempervictus commented Jan 20, 2024

This is caused, somehow by the act of passing a struct instead of a primitive type in the ctx; passing the svc_type as a u16 resolves the compiler error; but this means having to decompose all structs into members if passing something with complex references.

@sempervictus sempervictus changed the title Context passing (possibly due to multiple elements) creates opaque error Passing a struct in ctx creates opaque error Jan 20, 2024
@wcampbell0x2a
Copy link
Collaborator

Not at my computer, but could you try out the master branch? I think this is a duplicate of the fix MR here.

@sempervictus
Copy link
Author

@wcampbell0x2a - any chance you could merge #387 to master? Best thing since sliced bread for writing parsers for undocumented protocols where you need that "whatever is left over" set of bytes to still get parsed while you figure out the preceding structures/deps. Currently using it so would be swell to not have to comment-out the WIP stuff to test the stuff i think should work :)

@wcampbell0x2a
Copy link
Collaborator

Merged

@sempervictus
Copy link
Author

Just about there. Trying to pass the struct by reference results in:

169 |     #[deku(ctx = "hdr")]
    |                  ^^^^^ expected `SvcHeader`, found `&SvcHeader`

and trying to do it by value violates the borrow checker:

169 |     #[deku(ctx = "*hdr")]
    |                  ^^^^^^ move occurs because `*hdr` has type `SvcHeader`, which does not implement the `Copy` trait

Deriving Clone, Copy for the header struct seems to satisfy the checker though i'm not entirely sure what side-effects this has if the passed context is distinct from the actual data in the stream.

@wcampbell0x2a
Copy link
Collaborator

@sempervictus Checkout #411 for a fix for this. Sorry I didn't have time today to find an actual solution. I think.

@sempervictus
Copy link
Author

@wcampbell0x2a thank you, that PR's a brainfull so to speak... Lots of reading ahead on my end to actually figure out the codegen being done by those macros at some point 😄. That said, does cloning the pat type impact mutability of the enum's contents? If that's rebased off current master i'll give it a whirl when i go back to that piece of code.

If its not too much trouble, and you happen to know - what does the derivation of cloning/copying do for actual mutability of content given that we're working off an underlying byte stream? Protocol machinations such as proxies need to alter those existing streams in-flight (making the inability to use update on member structs mildly confounding/verbose to write without the member struct just using fields) and coupled with the borrow checker's constraints, the process can get "hacky" at times 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants