Search code examples
parsingrust

Rustlang deku generic type


I am currently working with Rust and the deku crate and face an optimization issue.
The task is quite simple, I would like to parse some binary data into into a Rust struct.

My code is this:

#[derive(Debug, PartialEq, DekuRead)]
pub struct EntryU32 {
    id: u8,
    value: u32,
}
#[derive(Deserialize, Debug, PartialEq, DekuRead)]

pub struct EntryU16 {
    id: u8,
    value: u16,
}
#[derive(Debug, PartialEq, DekuRead)]
pub struct BinData {
    entry1: EntryU32,
    entry2: EntryU16,
}
// which allows me to parse the binary via BinData::from_bytes(...)

But this approach requires a dedicated EntryStruct for each datatype → u8, i8, u16, … So I would like to use a generic one, something like the following one:

#[derive(Debug, PartialEq, DekuRead)]
pub struct Entry<T> {
    id: u8,
    value: T,
}
#[derive(Debug, PartialEq, DekuRead)]
pub struct BinData {
    entry1: Entry::<u32>,
    entry2: Entry::<u32>,
}

But this raises the error, that DekuRead is not implemented for type T. Full error message:

the trait bound `T: deku::DekuRead<'_, _>` is not satisfied
the following other types implement trait `deku::DekuRead<'a, Ctx>`:
  <bool as deku::DekuRead<'a, Ctx>>
  <isize as deku::DekuRead<'_, (Endian, deku::ctx::ByteSize)>>

I am not sure how to scope the datatype T such that DekuRead (and later DekuWrite) works properly. I have tried to bound it as shown below, but I currently bounds from one type of error to the other one.

pub struct Entry<T>
where
    T: DekuRead<'a>,

Solution

  • This is one of the few cases where you need a higher ranked trait bound (HRTB):

    #[derive(Debug, PartialEq, DekuRead)]
    pub struct Entry<T>
    where T: for<'a> DekuRead<'a>,
    {
        id: u8,
        value: T,
    }