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

Feature request: Provide compile time size hint when derive DekuRead & DekuWrite #518

Open
KmolYuan opened this issue Jan 20, 2025 · 0 comments
Labels
enhancement New feature or request

Comments

@KmolYuan
Copy link

It would be great if a constant size-hint value could calculate the static buffer size when derived from DekuRead, DekuWrite, or a new macro.

pub trait DekuSizeOf {
    /// Compile time size hint in bits (since deku supports bits)
    const SIZE_HINT_BITS: Option<usize>; // `None` if dynamic read/write length detected
                                         // `Some(n)` for static-size type
}

#[doc(hidden)]
pub const fn eval_size<T: DekuSizeOf>(rhs: Option<usize>) -> Option<usize> {
    option_size_add(T::SIZE_HINT_BITS, rhs)
}

#[doc(hidden)]
pub const option_size_add(a: Option<usize>, b: Option<usize>) -> Option<usize> {
    match (a, b) {
        (Some(a), Some(b)) => Some(a + b),
        (None, _) | (_, None) => None,
    }
}

// SIZE_HINT_BITS = Some(24) = eval_size::<u8>(eval_size::<u8>(eval_size::<u8>(Some(0))));
struct Rgb {
    r: u8,
    g: u8,
    b: u8,
}

// SIZE_HINT_BITS = Some(24) = eval_size::<u16>(option_size_add(Some(4), Some(4)));
struct U4Test {
    #[deku(bits = 4)]
    field_a: u8,
    #[deku(bits = 4)]
    field_b: u8,
    field_c: u16,
}

// SIZE_HINT_BITS = Some(8) = eval_size::<u8>(Some(0));
struct Header(u8);

// SIZE_HINT_BITS = Some(16) = eval_size::<u16>(Some(0));
struct Data(u16);

// SIZE_HINT_BITS = Some(24) = eval_size::<Header>(eval_size::<Data>(Some(0)));
struct SubTypeTest {
    header: Header,
    data: Data,
}

// SIZE_HINT_BITS = None = eval_size::<Vec<u8>>(option_size_add(Some(4), eval_size::<u8>(Some(0))));
struct VecTest {
    #[deku(update = "self.data.len()")]
    count: u8,
    #[deku(count = 4)]
    data_static: Vec<u8>,
    #[deku(count = "count")] // "count" is dynamic, so put `Vec<u8>::SIZE_HINT_BITS = None`
    data: Vec<u8>,
}

Attributes:

Not allowed: (for examples)

If we could support enums, the SIZE_HINT_BITS can be defined as the maximum byte size and all enum attributes should be supported.

@wcampbell0x2a wcampbell0x2a added the enhancement New feature or request label Jan 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants