apollo-ios icon indicating copy to clipboard operation
apollo-ios copied to clipboard

Use @nonexhaustive for codegen in enums

Open thomascatterall-toast opened this issue 3 months ago • 5 comments

Use case

Extensible enums has been accepted and would make a great addition to the codegen options.

Currently you have to dance around either: switching directly on the GraphQLEnum<Enum>, which requires a default case unwrapping directly the enum and exhaustively checking

When the enum changes in the schema, the first option provides no warning that your code has a new case to consider; the latter breaks the code entirely. Neither are great options.

This attribute is explicitly for the use case of public API that may be extended later, and provides the same behavior as non frozen enums in Library Evolution-enabled modules (which are very much a niche).

The end result would be that all gql enums could be switched over directly (you could drop the GraphQLEnum type, eventually) and would require an @unknown default case. Furthermore, you would receive a compiler warning when you had not handled a new case.

Describe the solution you'd like

No response

thomascatterall-toast avatar Sep 12 '25 16:09 thomascatterall-toast

Whoops, posted from my work account by mistake. Please address all follow-ups to this actual account :D

swizzlr avatar Sep 12 '25 17:09 swizzlr

Woah, this has totally flown under my radar so far, but it does totally solve our problem, and you're right that we would be able to remove GraphQLEnum (and the associated headaches).

I have been considering making a change where we deprecate GraphQLEnum and instead just generate an unknown case on each of the generated enums. But that would prevent the generated enums from having a RawValue and automatic synthesis of Equatable and Hashable conformance. @nonexhaustive resolves this for us completely.

If I'm reading this correctly, it looks like this is accepted, but hasn't been implemented in a stable version of Swift yet. As soon as it is, we can look into going in this direction. If I'm wrong and I can start using this today, let me know and I will add it to the beta for Apollo iOS 2.0.

AnthonyMDev avatar Sep 12 '25 18:09 AnthonyMDev

@AnthonyMDev it's been merged into the 6.2 release branch, but obviously it may not be in Xcode 26 because Apple (I have yet to even install the RC). https://github.com/swiftlang/swift/pull/82922

swizzlr avatar Sep 12 '25 18:09 swizzlr

Got it. We will probably not want to implement this for a while to give people time to migrate. We will revisit this in the future. Thanks for making us aware of it!

AnthonyMDev avatar Sep 12 '25 19:09 AnthonyMDev

No worries - but it's an opt-in feature for swift (like concurrency etc) so depending on how configurable you want the codegen on the apollo side it's probably something that could be provided as an option.

swizzlr avatar Sep 15 '25 13:09 swizzlr