-
Notifications
You must be signed in to change notification settings - Fork 155
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
Add StaticVariantsArray
trait and derive
#297
Add StaticVariantsArray
trait and derive
#297
Conversation
test: `StaticVariantsArray` macro tests
Apparently it fails CI because the new trait I added to |
Hi there, @Peternator7 ! Can I get some feedback on this one? I could split the tests into a separate PR, which would likely make the CI pass |
Hey @Syndelis , this looks really good! Don't worry too much about the CI if that's the only issue; it's been an annoying footgun with strum since early versions. |
What do you think about |
I'm not a fan of this name either haha. I think best case scenario is renaming Other than that, I really don't know what name would best suit it. I've considered |
This PR would remove the need for this snippet to have a const array/slice of all variants?: // Strum presently lacks a derive for this:
const VARIANTS: &'static [MyEnum] = MyEnum::ALL_VARIANTS.as_slice();
// Effectively a const compatible equivalent of: MyEnum::iter().collect()
impl MyEnum {
const ALL_VARIANTS: [Self; Self::COUNT] = {
// Cannot rely on `Option<Self>` to default to `None`, as conversion
// to output type is not possible? Thus use the first variant as a default:
let default = Self::variant_from(0);
let mut variants = [default; Self::COUNT];
// Cannot use for loop (or iterators with collect) in a const fn,
// Hence initializing an array and replacing default elements via while loop:
let mut i = 0;
while i < Self::COUNT {
variants[i] = Self::variant_from(i);
i+=1;
}
variants
};
// Must unwrap value due to no support for const traits,
// otherwise could have collected with adaptors over [Option<Self>]:
const fn variant_from(discriminant: usize) -> Self {
let Some(variant) = Self::from_repr(discriminant) else { panic!("Invalid discriminant provided") };
variant
}
} I was going to raise a feature request for that since it took a while to figure out a solution with all the My use-case is for input into
I think this issue is requesting the same feature here? It suggested My snippet above could also be a |
Hi there, @Peternator7! Just wondering if you think anything else must be done to this PR or #315 in order to merge them? |
@polarathene Divan can now use runtime arguments via the |
Just published version |
About this PR
This PR introduces a new trait
StaticVariantsArray
which defines an associated constantALL_VARIANTS: &'static [Self]
. Accompained to it is a derive that will create this array from anenum
composed of only unit-type variants.Motivation
While working in a UI project with ImGui, I stumbled upon this method, Ui::combo, which expects a slice and a mapping function to build the combobox's options. My options, as you might've guessed, are defined in an enumerator, which looks a little like this:
The user, however, wouldn't see those names and, instead, I implement
Into<char>
for the respective characters you can imagine.Presented with that problem, I could go for one of two solutions:
EnumVariantNames
's<enum>::VARIANTS
, which is a static slice of strings. The problem with that approach is that it would generate an array with the names of the variants, which could be desired in many cases, but is not on mine as you can see above;EnumIter
and collect the result into aVec
. While the application would work fine with this approach, it seems overkill to heap-allocate a vector whose elements we know at compile time.Considering those two points, I've decided to introduce this trait (and derive).
Concerns
My only concern with this implementation is the name of both the trait/derive and the associated constant. I believe
VARIANTS
is a more fitting name, but it is already taken. I thought about renaming that toVARIANT_NAMES
, but it feels like an unecessary breaking change, although I'd like to hear more opinions on this.Closing thoughts
This is my first public macro contribution and, while I think it's quite simple and small, I'd love to get feedback on the implementation!