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

Help passing context around #397

Closed
wcampbell0x2a opened this issue Jan 3, 2024 Discussed in #396 · 1 comment · Fixed by #398
Closed

Help passing context around #397

wcampbell0x2a opened this issue Jan 3, 2024 Discussed in #396 · 1 comment · Fixed by #398

Comments

@wcampbell0x2a
Copy link
Collaborator

Discussed in #396

Originally posted by alexjbuck January 2, 2024
I'm brand new to the Deku crate. Its really cool!

I'm looking to parse some binary packet data with this crate. The general structure of packets is a Header/Payload structure. The header is an Identifier and a total packet length (as u32).

My initial thought was to treat the payload section as an enum where the id is an external id passed from the header type through the context variable (referencing the docs)

Below is a minimal implementation for one variant but I'm getting a proc-macro error that I don't understand.

use deku::prelude::*;

#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
struct Packet {
    header: Header,
    #[deku(ctx = "*header")]
    payload: Payload,
}


#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
struct Header {
    kind: PacketType,
    length: u32,
}


#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(type = "[u8;4]", endian="big")]
enum PacketType {
    #[deku(id = b"INFO")]
    InfoType,
}


#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(ctx = "header: Header", id = "header.kind")]
enum Payload {
    #[deku(id = "PacketType::InfoType")]
    Info {
        #[deku(count = "header.length-8")]
        data: Vec<u8>
    },
}

fn main() {
    // let data: Vec<u8> = vec![0x54, 0x49, 0x4D, 0x45,0x00,0x00,0x00,0x0C, 0x00,0x00,0x00,0x10, 0x53, 0x46, 0x4F, 0x52, 0x00, 0x00, 0x00, 0xA0];
    let data : Vec<u8> = vec![0x49, 0x4E, 0x46, 0x4F, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x10];
    let mut rest = (data.as_ref(),0 as usize);

    let (_rest,val) = Packet::from_bytes(rest).unwrap();
    dbg!(val);
    dbg!(rest);
}

These are the errors:

error: proc-macro derive panicked
  --> src\main.rs:26:28
   |
26 | #[derive(Debug, PartialEq, DekuRead, DekuWrite)]
   |                            ^^^^^^^^
   |
   = help: message: called `Result::unwrap()` on an `Err` value: Error("expected `,`")

error[E0277]: the trait bound `Payload: deku::DekuRead<'_, _>` is not satisfied
 --> src\main.rs:7:14
  |
7 |     payload: Payload,
  |              ^^^^^^^ the trait `deku::DekuRead<'_, _>` is not implemented for `Payload`
  |
  = help: the following other types implement trait `deku::DekuRead<'a, Ctx>`:
            <bool as deku::DekuRead<'a, Ctx>>
            <isize as deku::DekuRead<'_, (Endian, deku::ctx::ByteSize)>>
            <isize as deku::DekuRead<'_, (Endian, deku::ctx::BitSize)>>
            <isize as deku::DekuRead<'_, Endian>>
            <isize as deku::DekuRead<'_, deku::ctx::ByteSize>>
            <isize as deku::DekuRead<'_, deku::ctx::BitSize>>
            <isize as deku::DekuRead<'_>>
            <i8 as deku::DekuRead<'_, (Endian, deku::ctx::ByteSize)>>
          and 155 others

For more information about this error, try `rustc --explain E0277`.
error: could not compile `test-rs` (bin "test-rs") due to 3 previous errors

I'd appreciate any pointers to what I may be doing wrong here.

wcampbell0x2a added a commit that referenced this issue Jan 3, 2024
Remove unwrap causing the following error when the EnumExt tried to infer
what type is was to return. An attribute could be added in the future to aid this,
but for now we will just not emit the deku_id() for this type of enum.
I decided in other causes (which aren't tested), to also remove the error
and just not emit the function also.

 help: message: called `Result::unwrap()` on an `Err` value: Error("expected `,`")

See #397
@alexjbuck
Copy link

alexjbuck commented Jan 3, 2024

#398 appears to have fixed the issue! My case compiles and runs successfully. I did have to fix two issues: first I was moving the header via context instead of passing a reference, and second, the byte array input I gave encoded the u32 length as big-endian but the struct didn't tell Deku that, so it was trying to decode the length as little-endian (system default), so it didn't think there were enough bytes to fill the vec (technically true!), but once I fixed that it was all good.

wcampbell0x2a added a commit that referenced this issue Jan 16, 2024
* Fix unknown id Type for EnumExt::deku_id()

Remove unwrap causing the following error when the EnumExt tried to infer
what type is was to return. An attribute could be added in the future to aid this,
but for now we will just not emit the deku_id() for this type of enum.
I decided in other causes (which aren't tested), to also remove the error
and just not emit the function also.

 help: message: called `Result::unwrap()` on an `Err` value: Error("expected `,`")

See #397

* clippy

---------

Co-authored-by: Emmanuel Thompson <[email protected]>
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

Successfully merging a pull request may close this issue.

2 participants