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

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

Open
Bubbler-4 opened this issue Sep 26, 2023 · 2 comments
Open

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

Bubbler-4 opened this issue Sep 26, 2023 · 2 comments

Comments

@Bubbler-4
Copy link

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:

  • Output type: I believe it should be usize by default, but it would be also nice to preserve the repr if given (and explicitly assigned values).
  • Derive macro name: IntoInteger? Maybe IntoUsize and IntoReprType seprarately?
@polarathene
Copy link

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
Copy link

Zizico2 commented Jul 4, 2024

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.

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

3 participants