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

Use custom derive macros for all derive functionality #22

Open
15 tasks
kupiakos opened this issue Sep 6, 2024 · 1 comment
Open
15 tasks

Use custom derive macros for all derive functionality #22

kupiakos opened this issue Sep 6, 2024 · 1 comment

Comments

@kupiakos
Copy link
Owner

kupiakos commented Sep 6, 2024

This would replace #11 and #12.

The current detection of Debug can be kept as an ergonomic bonus, since std/3rd party derives using the variants of an open enum are unlikely to work correctly.

Design

The #[open_enum] macro declares an #[open_enum_variants = { Name0 = 0, Name1 = VALUE1, ... }] inert attribute on the emitted struct. This attribute is consumed by the derive macros declared in open_enum, so most will work whether the derive macro is interpreted before or after #[open_enum].

As done today, PartialEq and Eq are always implemented on open enums so they work in match.

These common derive macros work without interception:

  • PartialOrd
  • Ord
  • Hash

derive macros to consider, including additional nice-to-haves:

  • ToStr - to an Option<&'static str> with the name, or None if not a known variant. When allow_alias is enabled, the first defined variant wins.
  • ToCStr - to an Option<&'static ffi::CStr> with the name, or None if not a known variant. When allow_alias is enabled, the first defined variant wins. Might want to gate this on optimize_for_size.
  • Debug is captured specially today, this would still be captured and replaced with the open-enum derive.
  • FromRepr - implements From<$repr> for the open enum. Only works when the repr is explicit
  • TryFromKnownRep - implements TryFrom<$repr> for the open enum, checking for variants. Only works when the repr is explicit
  • ToRepr - implements Into<$repr> for the open enum. Only works when the repr is explicit
  • FromStr
  • FromPrimitive - implements FromPrimitive, allowing only known variants.
    • Requires a #[from_known_only = $bool] attribute
    • Requires the optional num_traits = "0.2" feature
  • Default Handle Default #23

Size optimization

  • A #[cfg(feature = "optimize_for_size")] can switch between fast lookup and small code size.
  • Names can be stored with an array of pointer-to-c-strings instead of array of pointer + size. However, this does make ToStr more slow than it otherwise would be.
  • Names and values can be sorted so that a binary search can be performed for either lookup. Both the algorithm and the extra sorted array would be extra code size.
  • "Is known value" and "Lookup name index" could be optimized for simpler non-contiguous ranges by using e.g. a u64 bit array.

Performing the above operations at const time if possible is strongly preferred since it can perform these optimization with nonliteral discriminants.

@kupiakos
Copy link
Owner Author

kupiakos commented Sep 7, 2024

Alternative design: #[open_enum] implements an EnumInfo trait that contains the necessary info to implement everything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant