binary-layout icon indicating copy to clipboard operation
binary-layout copied to clipboard

Automatic support for repr(int) enums

Open lvella opened this issue 1 year ago • 5 comments
trafficstars

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,
}

lvella avatar Apr 07 '24 17:04 lvella

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.

smessmer avatar Apr 08 '24 01:04 smessmer

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?

lvella avatar Apr 08 '24 12:04 lvella

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.

smessmer avatar Apr 08 '24 20:04 smessmer

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.

lvella avatar Apr 17 '24 21:04 lvella

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

  • Can we just call it #[derive(LayoutAs)] instead of #[derive(LayoutAsEnumRepr)]?
  • Can we make writing fallible by using TryInto instead of Into?
  • Can we make it independent from #[repr] so it also works with non-enum types? Maybe #[layout_as(u8)]? We could even allow deriving for multiple types like #[layout_as(u8, u16)].
    • We can consider not requiring the layout_as attribute if repr is already present, but I think that only makes sense if we also derive TryFrom and TryInto for them so it works with enums out of the box and without any manual extra code. But I'm not sure yet if we should or shouldn't do that, maybe better to be conservative and require users to specify both layout_as and derive TryFrom and TryInto for now.
  • We should probably add a couple more tests

smessmer avatar Apr 27 '24 20:04 smessmer