Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Can't add CaseIterable on Apollo-generated enum #399

Closed
guillaume-roux opened this issue Oct 30, 2018 · 6 comments
Closed

Can't add CaseIterable on Apollo-generated enum #399

guillaume-roux opened this issue Oct 30, 2018 · 6 comments
Labels
codegen Issues related to or arising from code generation enhancement Issues outlining new things we want to do or things that will make our lives as devs easier
Milestone

Comments

@guillaume-roux
Copy link

Hello,

We're trying to iterate on the Enum generated from the schema, so we've tried to add CaseIterable to it but Swift won't allow that due to the __unknown() case in the Enum.

Is there a way to iterate on the enums values apart from parsing the schema.json again?
Could Apollo maybe generate an AllCases constant holding all-bar-unknown value cases so we can get that rather than resort to CaseIterable?

@guillaume-roux guillaume-roux changed the title Can't add CaseIterable on Apollo-generate enum Can't add CaseIterable on Apollo-generated enum Oct 30, 2018
@zigfreid5
Copy link

zigfreid5 commented Jan 23, 2019

I implemented a temporary workaround based on some other suggestions for similar issues.
You can add CaseIterable conformance in an extension and still validate proper implementation by using something like this:

extension Gender: CaseIterable {
    public static var allCases: [Gender] {
        @available(*, unavailable)
        func _assertExhaustive(for gender: Gender) {
            switch gender {
            case .male, .female, .other, .notProvided, .unknown:
                break
            }
        }
        return [.male, .female, .other, .notProvided]
    }
}

The nested function is marked as unavailable so you can't call it, but it will break your build if the schema changes and messes with the enum cases. As long as you keep the array of cases updated, this allows you to have your CaseIterable and ignore the unknown case.

The problem with the codegen goes deeper than CaseIterable, however, and I think a proper fix would be to add an option to skip generation of unknown cases for enums altogether.

Another issue I came across is that I had been initializing enum cases with the rawValue init, but if the string value isn't an exact match, you end up with an unknown("value") instead of what you expected. It should be a failable initializer and produce nil, but because of the unknown case and generated initializer, you will never get nil. In my opinion, this is bad implementation and should be fixed.

@Mountainbrussells
Copy link

Mountainbrussells commented Feb 14, 2019

I also believe adding caseiterable to the generated enums would be a good idea, I used the same workaround as @zigfreid5

@designatednerd
Copy link
Contributor

I'm fairly new so I have to make sure that we're not doing anything too nuts that would make non-automatic CaseIterable conformance impossible, but CaseIterable is my jam and I'd love to make everything conform to it.

@designatednerd designatednerd added codegen Issues related to or arising from code generation enhancement Issues outlining new things we want to do or things that will make our lives as devs easier labels Jul 15, 2019
designatednerd added a commit to apollographql/apollo-tooling that referenced this issue Jul 26, 2019
@designatednerd
Copy link
Contributor

Hi! Tooling PR 1441 adds generated CaseIterable conformance for all known cases. Please head over there and let me know if you see any problems with that implementation!

@designatednerd designatednerd added this to the 0.14.0 milestone Jul 26, 2019
designatednerd added a commit to apollographql/apollo-tooling that referenced this issue Jul 29, 2019
designatednerd added a commit to apollographql/apollo-tooling that referenced this issue Jul 30, 2019
designatednerd added a commit to apollographql/apollo-tooling that referenced this issue Aug 3, 2019
JakeDawkins pushed a commit to apollographql/apollo-tooling that referenced this issue Aug 5, 2019
* Add `CaseIterable` conformance to swift Enums

Addresses apollographql/apollo-ios#399

* Don't use `as!` when the thing being unwrapped is a double-optional

Addresses apollographql/apollo-ios#530

* Use multi-line string literals for operations and fragments

Addresses apollographql/apollo-ios#179

* update changelog

* fix swift tests failing on CI

(why don't these fail locally?)

* back out multiline codeblock changes

* add comments with original graphql statement to operation definitions

* add comments with graphql statements to fragment definitions

* update operation definition in the general tests

* trim out additional whitespace

* update changelog

* don't add newlines back in when trimming whitespace

* add comments to added test cases

* do not attempt to strip whitespace from things which include multi-line string literals

* fix alignment sillies

* slightly javascriptier code

* yep, guess that needs the return after all too

* remove the brackets and you can also remove the return!

* nil-coalesce to `none` when pulling optional out of GraphQL map
@designatednerd
Copy link
Contributor

Built-in CaseIterable support for known cases shipped with 0.14.0!

@designatednerd
Copy link
Contributor

designatednerd commented Aug 7, 2019

Do note that if you used @zigfreid5's workaround, you'll need to remove it since it'd be a redeclaration of CaseIterable conformance once you upgrade to 0.14.0

essaji pushed a commit to essaji/apollo-tooling that referenced this issue Aug 25, 2019
* Add `CaseIterable` conformance to swift Enums

Addresses apollographql/apollo-ios#399

* Don't use `as!` when the thing being unwrapped is a double-optional

Addresses apollographql/apollo-ios#530

* Use multi-line string literals for operations and fragments

Addresses apollographql/apollo-ios#179

* update changelog

* fix swift tests failing on CI

(why don't these fail locally?)

* back out multiline codeblock changes

* add comments with original graphql statement to operation definitions

* add comments with graphql statements to fragment definitions

* update operation definition in the general tests

* trim out additional whitespace

* update changelog

* don't add newlines back in when trimming whitespace

* add comments to added test cases

* do not attempt to strip whitespace from things which include multi-line string literals

* fix alignment sillies

* slightly javascriptier code

* yep, guess that needs the return after all too

* remove the brackets and you can also remove the return!

* nil-coalesce to `none` when pulling optional out of GraphQL map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
codegen Issues related to or arising from code generation enhancement Issues outlining new things we want to do or things that will make our lives as devs easier
Projects
None yet
Development

No branches or pull requests

4 participants