Peternator7 / strum

A small rust library for adding custom derives to enums
https://crates.io/crates/strum
MIT License
1.8k stars 151 forks source link

Feature request: A function to convert to integer by variant #298

Open Bubbler-4 opened 1 year ago

Bubbler-4 commented 1 year ago

For example, given an enum like this

enum Minituple {
    Zero,
    One(i32),
    Two(i32, i32),
    More(Vec<i32>),
}

I would like to have a function that converts each variant to a unique integer, like this:

impl Minituple {
    pub fn into_integer(&self) -> usize {
        match self {
            Zero => 0,
            One(_) => 1,
            Two(_, _) => 2,
            More(_) => 3,
        }
    }
}

Considerations:

polarathene commented 1 year ago

You can use the EnumDiscriminants feature and cast with as to the primitive number type you want:

#[derive(EnumDiscriminants)]
enum Minituple {
    Zero,
    One(i32),
    Two(i32, i32),
    More(Vec<i32>),
}

impl Minituple {
  fn into_integer(&self) -> usize {
    let discriminant: MinitupleDiscriminants = self.into();
    discriminant as usize

    // Alternatives:
    // - `Into::<MinitupleDiscriminants>::into(self) as usize`
    // - `MinitupleDiscriminants::from(self) as usize`
  }
}

// ...

// Outputs `discriminant: 2`
println!("discriminant: {}", Minituple::Two(42, 24).into_integer());

So technically, what you'd want is instead a method like as_discriminant()? You could then follow with as usize, or impl your own method to wrap that?

Zizico2 commented 4 months ago

I think even just a IntoRepr would be useful. I realize this could literally just wrap as usize, or similar. But for example, if used with #[repr(_)] this would mean you have similar behaviour to FromRepr, that would expose an into_repr function with a return type that respects the #[repr(_)].

And, more subjectively, this would allow use not to use as. From my experience there are some code bases that try to avoid as, preferring the try_into alternatives, where possible (mostly (u)int[8|16|32|64|128] convertions). This would be one more place where avoiding as would be possible.