leancodepl / contractsgenerator-dart

Dart contracts client generator for a CQRS API
3 stars 1 forks source link

Generate non-exhaustive enums #94

Open shilangyu opened 2 months ago

shilangyu commented 2 months ago

Problem

Currently the generated enums assume to be exhaustive. This is not forward compatible and can break applications severely when a new enum variant is added.

Solution

This issue is about always generating an extra enum variant unknown. Then, all unknown enum values should be deserialized into that. Additionally a new config field should be added that allows the bring back the old behavior. This will be needed for compatibility with existing users.

Implementation

Consider an enum E with variants a and b. The most obvious solution would be to generate the following enum:

enum E {
    a,
    b,
    unknown
}

The issue here is that now the client is allowed to send E.unknown to the backend, which should not be allowed. We can make it a bit more type safe. Instead we can generate the following:

sealed class EBase {}

enum E implements EBase {
    a,
    b
}

final class UnknownEnumVariant implements EBase {
    const UnknownEnumVariant._();
}

UnknownEnumVariant would be shared by all enums. The private constructor makes it not constructable outside of the contracts file. This makes the types more complicated, but makes the API safe.