smessmer / binary-layout

The binary-layout library allows type-safe, inplace, zero-copy access to structured binary data. You define a custom data layout and give it a slice of binary data, and it will allow you to read and write the fields defined in the layout from the binary data without having to copy any of the data. It's similar to transmuting to/from a #[repr(packed)] struct, but much safer.
Apache License 2.0
66 stars 9 forks source link

Automatic support for repr(int) enums #27

Open lvella opened 3 months ago

lvella commented 3 months ago

I am not entirely sure how to do it, but it would be nice if LayoutAs was automatically implemented for repr(some_primitive) enums.

Or at least provide a procedural macro for us to #[derive(LayoutAs)] our enums.

Like:

#[derive(LayoutAs)]
#[repr(u8)]
enum ExampleEnum {
    Variant1 = 1,
    Variant2 = 2,
    Variant3 = 3,
}
smessmer commented 3 months ago

Thanks for reaching out. I like the derive macro idea. Might not get time to implement it myself any time soon but I'd be happy to accept a PR for it.

lvella commented 3 months ago

After looking a bit into it, I think a better approach would be a #[derive()] macro that will automatically implement LayoutAs for any type that implements Into<U> and TryFrom<U>. The user may then use num_enum crate to derive those implementations to their enum types.

What do you think?

smessmer commented 3 months ago

It should probably be TryInto instead of Into but yes that makes sense as well. We could also offer both, derive for types that have TryInto and TryFrom and as additional convenience allow it on enums with repr as well.

lvella commented 3 months ago

Hi, I have a barely tested attempt here: https://github.com/lvella/binary-layout-derive

If you like it, I can make a PR to include the crate in this repo, but I would need to reorganize it into a workspace with two crates, binary-layout and binary-layout-derive, like serde or other projects with procedural macros.

smessmer commented 2 months ago

I'm ok with introducing a separate crate. Your approach generally looks good, couple of comments: