sharksforarms / deku

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't use enum inside structs

wooden-worm opened this issue · comments

Is that not supported or am I doing something wrong?

#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(endian = "big")]
struct MyStruct {
    my_enum: MyEnum,

    field_1: u32,
}

#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(type = "u8")]
enum MyEnum {
    A = 0,
    B = 1,
}

Error:

 #[derive(Debug, PartialEq, DekuRead, DekuWrite)]
    |                            ^^^^^^^^
    |                            |
    |                            expected `()`, found enum `Endian`
    |                            arguments to this function are incorrect

Using endian sets a Ctx to the child struct. You can either ignore the endian (since this a u8), or use it.

[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(endian = "big")]
struct MyStruct {
    my_enum: MyEnum,

    field_1: u32,
}

#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
// Ignore
#[deku(type = "u8", ctx = "_ctx_endian: Endian")]
// Or use
//#[deku(type = "u8", endian = "ctx_endian", ctx = "ctx_endian: Endian")]
enum MyEnum {
    A = 0,
    B = 1,
}

Thank you @wcampbell0x2a. I do have another question regarding enums: when I use #[deku(id_pat = "_")], can I use #[repr(u8)] or do I have to specify #[deku(id = "...")] for each variant?

#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(type = "u8", ctx = "_ctx_endian: Endian")]
#[repr(u8)]
enum MyEnum {
    A = 0,
    B,
    #[deku(id_pat = "_")]
    Unknown(u8),
}

// The above does not work. error:
#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
   |                            ^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
   |
   = note: this error originates in the derive macro `DekuRead` (in Nightly builds, run with -Z macro-backtrace for more info)

This works though

#[derive(Debug, PartialEq, DekuRead, DekuWrite)]
#[deku(type = "u8", ctx = "_ctx_endian: Endian")]
enum MyEnum {
    #[deku(id = "0x00")]
    A,
    #[deku(id = "0x01")]
    B,
    #[deku(id_pat = "_")]
    Unknown(u8),
}

Yah you need to specify for current deku to work. I would need to look at the code, but I think it's for the same reason this doesn't build:

#[repr(u8)]
enum MyEnum {
    A = 0,
    B,
    Unknown(u8),
}

fn main() {
    let a = MyEnum::A as u8;
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f875a28bcf0277b798d52eaf69f8371b

Thanks for the help @wcampbell0x2a, I appreciate it. I'll let you decide whether to close this issue or not.