Hard coding value to attach to Enum

#1
  1. The following code does NOT do what I want it to do:
pub enum Gender {
    Male, Female
}


pub struct Person {
    gender: Gender,
    age: i32,
    name: String,
}

pub enum Simpson {
    Bart(Person),
    Homer(Person),
    Marge(Person),
    Lisa(Person),
    Maggie(Person),
}
```

2. I am happy with the Gender/Person definition. I am not happy with the Simpson definition.

3. What I want to say is: the only valid values for Simpson are: Bart, Homer, Marge, Lisa, Maggie.

4. I also want to, in place, define a "Person" value to attach to each Simpson.

I could do this via:

```
impl Simpson {
  pub fn to_person(&self) -> Person {
    match self with {
      Bart => ....,
      Homer => ...,
    ....
  }
  }
}

But, if possible, to avoid the repetition / potential for error, I’d like to define the Person in place where the Bart/Homer/Marge/Lisa/Maggie are defined.

  1. Does this question even make sense? If so, is there a way to do this?
1 Like
#2
pub struct Simson {
    person_data: Person,
    name: Name
}

pub enum Name {
    Bart,
    Homer,
    Marge,
    Lisa,
    Maggie,
}

Something like this?

You could also do

pub enum Simson {
    Bart,
    Homer,
    Marge,
    Lisa,
    Maggie,
}

// instead of the ..., you put in your data.
impl Simson {
    fn to_person(name: Simson) -> Person {
        use self::Simson::*;
        match name {
            Bart => Person { ... },
            Homer => Person { ... },
            Marge => Person { ... },
            Lisa => Person { ... },
            Maggie => Person { ... },
        }
    }
}

like you said

1 Like
#3
  1. This certainly answers the question I stated. Thanks!

  2. The question I meant to ask was: is there any solution besides this one, i…e besides decalring this other function?

#4

You could define static globals for each of the Simsons

1 Like
#5

You’re basically asking to link an expression to a certain enum value without having boilerplate code in between. That makes either procedural or declarative macro another option.

Defining a declarative macro, with a key-value input interface, grants the quickest results. More information can be found here: https://doc.rust-lang.org/rust-by-example/macros.html

I’m not gonna provide an example of a declarative macro because what it should do is rather complex to work out on top of my head;

  1. Accept one or more [Simpson name] => [Person value (expr)]
  2. Recursively collect all Simpson names for enum creation
  3. Implement Into<Person> for Simpson for all variants.

Things to consider with this approach, depending on your needs;

  • You probably want to accept other identifiers to name the generated structs (Person and Simpson) otherwise, you’re limited to one call per module due to name collisions;
1 Like
#6

@zeroexcuses, do you need an enum here or would you be interested in expressing the Simpsons at a type level? It seems like gender, age, and name can be expressed as associated constants or types on a trait, implemented for unit structs representing the Simpsons.

Not sure if you intend to store them in a homogeneous container, or otherwise need to dynamically abstract over them.

Also, you can just use constants to represent them all, ie:

pub const BART: Simpson = Simpson(Gender::Male, 20, "Bart");

It’s not clear how you intend to use this stuff, so hard to say what will work best.

1 Like
#7

This is a messy/proprietary XY problem. I need to rethink my problem constraints.