bitflags icon indicating copy to clipboard operation
bitflags copied to clipboard

Idea: represent the flag constants as an enum

Open e00E opened this issue 3 years ago • 4 comments

I had the idea the flags instead of being associated constants could be an enum that is repr of the same underlying integer type. Then the full struct can be thought of as a set like container for the enum values. Having the enum has some advantages in type safety and would allow you to easily implement an iterator over the set flags. One significant change is that some operations would be duplicated. For example in the set (flags struct) you can insert, remove, toggle with another set (which is what the crate does at the moment) but you can also do the same operations on individual flag enum values.

Sketch of generated code:

struct Flags(u32) {
    #[repr(u32)]
    enum Flag {
        A = 1,
        B = 2,
        C = 4,
    }

    pub fn insert(&mut self, other: Flags);
    pub fn insert_single(&mut self, other: Flag);
}

Overall this probably doesn't fit in nicely enough with the current functionality but I wanted to bring it up since I didn't see it discussed before through the Github search.

e00E avatar May 17 '21 08:05 e00E

I actually also just came here to post this same idea! Main motivation is the auto-complete will actually work in IDEs.

sam0x17 avatar May 18 '21 14:05 sam0x17

So if I understand correctly, the Flag enum would only be used for stuff like iterating and inserting single flags? Because the result of operations like | couldn't be stored as a Flag, as that would lead to undefined behaviour.

Having the enum has some advantages in type safety and would allow you to easily implement an iterator over the set flags.

Could you elaborate? I don't see how this helps in implementing an iterator, nor do I think it would be a big help in type safety, as a huge part of bitflags is dealing with sets of flags (if you're only using individual flags, you might as well use a normal enum).

Main motivation is the auto-complete will actually work in IDEs.

I think that's a problem with macros, not with associated constants vs enum variants.

konsumlamm avatar Jun 26 '21 21:06 konsumlamm

As you noticed having this enum allows you to distinguish a single flag from a set of flags. I understand that the usual use case for bitflags is the set but sometimes you might want to work with a single flag which the set cannot represent. For example this is the case when iterating over all the set flags in a set. The enum has more type safety in this case than a plain integer.

e00E avatar Jun 27 '21 07:06 e00E

I think there are legitimate scenarios where it does make sense to be able to loop over both the "enabled" flags set and the "unenabled" flags set without much fuss.

sam0x17 avatar Jun 27 '21 22:06 sam0x17

In the last few years IDE support has come a long way for Rust. CLion for instance can see through macros and autocomplete on the associated constants you specify in your flags types.

CLion IDE with autocomplete of bitflags constants

This is an interesting suggestion, but I don't think it's something we'd consider for bitflags. That doesn't mean it's not worth spinning up some kind of new enumflags library for it!

KodrAus avatar Oct 08 '22 00:10 KodrAus