Proposal B — enum variants that carry data
Status: under discussion · See the section overview for the question all three answer
The idea: an enum's variants can carry data, as in Rust, Swift and Kotlin's
sealed classes. This is the 2024 enum_variant_associated_kind proposal; the
enum guide already mentions it
(Encrypt(EncryptionAlgorithm)).
Shape
enum EntityAction {
@id = 0x00
Attack(target: u32)
@id = 0x01
Interact(target: u32, hand: Hand)
@id = 0x02
InteractAt(target: u32, hand: Hand, x: f32, y: f32, z: f32)
@id = 0x03
Swing
}
The generated Rust is the same as Proposal A's.
The case for it
- One construct for "one of these", whether the variants carry data or not.
- It mirrors the generated Rust exactly, and reads naturally to Rust, Swift and Kotlin users.
- Payloads are inline, with no extra struct per variant.
- It continues an existing proposal, already pointed to from the guide.
- Adding data to one variant later is a change to the same declaration,
not a move from
enumtounion.
The case against
- Enums get harder. A
@phasesenum, an enum with explicit numeric values on a packet wire, or a C-style enum must not carry data, so rules have to forbid it in those places. - "Enum" means named numbers to people coming from C, C++, Protobuf, Java and TypeScript.
- TypeScript renders it as a discriminated union, not a TS
enum, so the generated code's shape doesn't match the schema's word. - The untagged inline
union(A B)stays beside it, so "one of these" still has two spellings with different wire behaviour.
When this would be the right call
When the audience is mainly Rust-like and one construct for all sum types matters more than keeping enums plain.