Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Make the generated enums real enums #297

Open
ValentinVignal opened this issue Feb 9, 2022 · 3 comments
Open

Make the generated enums real enums #297

ValentinVignal opened this issue Feb 9, 2022 · 3 comments

Comments

@ValentinVignal
Copy link
Contributor

Right now, the generated enums are not "real" dart enums, it is a class with static consts:

class GMyEnum extends EnumClass {
  const GMyEnum._(String name) : super(name);

  static const GMyEnum ENTRY_0 = _$gMyEnumEntry0;

  static const GMyEnum ENTRY_1 = _$gMyEnumEntry1;

  static Serializer<GMyEnum> get serializer =>
      _$gMyEnumSerializer;
  static BuiltSet<GMyEnum> get values =>
      _$gMyEnumValues;
  static GMyEnum valueOf(String name) =>
      _$gMyEnumValueOf(name);
}

The issue is that, when doing a switch/case, dart complains because it doesn't know I've specified all the possible cases, and I lint errors. As an example the code bellow gets an analysis error:

The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type.
Try adding either a return or a throw statement at the end.dart[body_might_complete_normally](https://dart.dev/diagnostics/body_might_complete_normally)

which wouldn't happen if GMyEnum was a proper dart enum.

String myString(GMyEnum myEnum) {  // <- Lint error The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type. Try adding either a return or a throw statement at the end. dart[body_might_complete_normally](https://dart.dev/diagnostics/body_might_complete_normally)
  switch (myEnum) {
    case GMyEnum.ENTRY_0:
      return 'entry0';
    case GMyEnum.ENTRY_1:
      return 'entry1';
  }
}

Is there a reason it cannot be made as a "real" enum ?
If you need properties or getters on the entries, you could generate extensions on the generated enum.

@ValentinVignal ValentinVignal changed the title Make the generated enums read enums Make the generated enums real enums Feb 9, 2022
@knaeckeKami
Copy link
Collaborator

So, this project used built_value to generate immutable objects, which support ==/hashCode and json serialization.
And built_value does not use dart enums, but custom enum objects, for reasons explained here: https://github.com/google/built_value.dart#enum-class

Now, built_value was written before Dart 2.0 and Dart enums have improved since then. So possibly, the authors would take a different decision if they were designed built_value today.

So, generating Dart enums and making them work with built_value serialization is not trivial and I'm not sure if it's even possible.
Switching to Dart enums would also be a breaking change.

So I'm afraid this is not something that is feasible at the moment.

If someone wants to work on this, PR's are welcome though (preferably with a switch so we can support both the current behavior and standard enums to avoid a breaking change).

If in the future, built_value properly supports Dart enums, I will reconsider.

@knaeckeKami
Copy link
Collaborator

There's an issue for that on built_value: google/built_value.dart#1171

@knaeckeKami
Copy link
Collaborator

Another note: consider using enum fallbacks (see https://pub.dev/packages/gql_build#provided-builders ).

Otherwise, if the server adds an additional enum in the future and the client is not updated with the latest schema, parsing the response with the unknown enum value would fail. This is also something that built_value provides out of the box.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants