rustenums

Check if enum is unit-only and contiguous


Rust language allows to create fancy enum variants like this:

enum MyEnum {
    UnitVariant,
    TupleLikeVariant(i32, i32),
    StructLikeVariant {
        a: i32,
        b: i32,
    },
}

Also rust allows enum's discriminants to have "holes" (to not be contiguous):

enum HalfLifeGame {
    // ... = 0
    One = 1,
    Two = 2,
    // ... = 3
    Alyx = 4,
}

How do I check that a given enum:

a) Is unit only (and not zero variant too)

b) Has no gaps in discriminants (i.e. all enum's discriminants correspond to some contiguous range 0..n)

?

Ideally I would prefer something like this:

const fn is_unit_only_and_contiguous<T>() -> bool
where
    /* T is enum */
{
    /* ... */
}

Solution

  • Use the Contiguous derive macro from the bytemuck crate. The trait implementation it generates has methods for conversions if that's what you're after. Though it does require explicit #[repr(int)] annotations as well.

    Here's how it could look in your code:

    #[derive(Contiguous)]
    #[repr(u8)]
    enum MyEnum {
       A = 0,
       B = 1,
       C = 2,
    }
    

    And then use T: Contiguous where you'd like that constraint.