DRY enum struct-like variants

I have encountered the want several times recently where in an enum with only struct-like variants all but a few fields are shared both in name and in type between the variants.

Example:

pub enum Foo {
    Var1 {
        wealth: i32,
        likeable: bool,
        age: i16
    },
    Var2 {
        wealth: i32,
        likeable: bool
    }
}

It would be vary nice, both from a readability standpoint and a DRY standpoint if it were possible to do the following (or something like it):

pub enum Foo {
    Var1 {
        likeable: bool
    },
    Var2,
    { // blank block 
        wealth: i32,
        likeable: bool
    }
}

The two examples would have the same fields. As for errors this would not be allowed if some of the variants were tuple-like. As for implementation, I am not that well versed in how it is handled currently but to make it the most similar in each case I would say that the best place to put them is that the top of every variant.

Or, to make it even more versatile the fields are just not added to tuple-like variants

Currently, this is usually done via a inner: FooInner field with the wealth and likeable fields.

Bonus points for functionality: if the “global” members are accessible without matching the variant out.

[[ Side note: I don’t see struct-like variants much; I mostly see (primarily) all-newtype-variants or (sometimes) all-tuple-variants. ]]

2 Likes

Interesting maybe parsing (which is what I am doing) lends itself to using struct-like variants

When I need this, I usually just “transpose” my type setup and put the enum in a struct, factoring the common fields out and into the struct. From what I can tell it’s completely equivalent.

I would also be very surprised to see enums, which are sum types, contain common fields — that would make them a product type (a product of the “global” fields and the sum of all the other fields in the individual variants). I don’t think it’s a good idea to conflate sum and product types; let’s just use both for their sole purpose.

2 Likes

Syn, the most battle-tested sea-of-enums uses struct-newtype-variant everywhere. The key benefit of which is that the variant now has a type you can talk about.

Honestly, until we find a way for variants-as-types or types-as-variants, the newtype-variant seems broadly useful for things like this. (With macros for dryer code.)

1 Like

IIRC the variants-as-types RFC has been accepted.

No, it’s still open though I think there is a future-compat lint in that protects against -> Enum::Variant ambiguity where Variant is also an associated type. Last comment on the RFC was in January.

1 Like

Ah, you are right… I think I got it mixed up with another, accepted one.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.