- 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.
- Does this question even make sense? If so, is there a way to do this?
1 Like
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
You could define static globals for each of the Simsons
1 Like
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: macro_rules! - Rust By Example
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;
- Accept one or more
[Simpson name] => [Person value (expr)]
- Recursively collect all Simpson names for enum creation
- 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
@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
This is a messy/proprietary XY problem. I need to rethink my problem constraints.