{"id":16886654,"url":"https://github.com/alisoftware/generate-enum-allvalues","last_synced_at":"2025-04-11T14:02:28.317Z","repository":{"id":137560022,"uuid":"69207773","full_name":"AliSoftware/generate-enum-allvalues","owner":"AliSoftware","description":"Automatically generate a `static let allValues` for your Swift enums","archived":false,"fork":false,"pushed_at":"2016-09-26T19:34:18.000Z","size":11,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-05T08:51:57.498Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AliSoftware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-26T03:01:56.000Z","updated_at":"2019-02-06T09:03:00.000Z","dependencies_parsed_at":"2023-06-13T15:45:52.219Z","dependency_job_id":null,"html_url":"https://github.com/AliSoftware/generate-enum-allvalues","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliSoftware%2Fgenerate-enum-allvalues","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliSoftware%2Fgenerate-enum-allvalues/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliSoftware%2Fgenerate-enum-allvalues/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliSoftware%2Fgenerate-enum-allvalues/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AliSoftware","download_url":"https://codeload.github.com/AliSoftware/generate-enum-allvalues/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233753377,"owners_count":18724823,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T16:40:34.637Z","updated_at":"2025-01-13T14:19:36.881Z","avatar_url":"https://github.com/AliSoftware.png","language":"Swift","readme":"# generate-enum-allValues\n\nThis tiny Swift script allows to generate an implementation for `static let allValues: [Self]` on all `enum` that are marked as conforming to `CasesEnumerable`\n\nThis way if you declare:\n\n```swift\nenum Directons: CasesEnumerable { case north, south, east, west }\n```\n\nThe script will be able to generate:\n\n```swift\nextension Directions {\n  static let allValues: [Directions] = [.north, .south, .east, .west]\n}\n```\n\n## Requirements / Installation\n\n* Install [SourceKitten](https://github.com/jpsim/SourceKitten)\n* Download the `generate-enum-allValues` Swift script\n* Ensure the script has executable flag (`chmod +x generate-enum-allValues`)\n\n## Usage\n\n* Declare an empty protocol `protocol CasesEnumerable {}` in your source code somewhere\n* For every `enum` for which you want an `allValues` implementation, mark them as conforming to this `CasesEnumerable` protocol\n* Run `sourcekitten structure` on your source code and pipe the result to the `generate-enum-allValues` Swift script to generate the implementation\n\n```sh\nsourcekitten structure --file inputfile.swift | generate-enum-allValues\n```\n\nThe Swift script will use the AST analysis from SourceKitten to find all the `enum` in your code that conform to `CasesEnumerable`, go over all the `case` declarations they contain, and generate the appropriate implementation for the `static let allValues` property in an `extension`.\n\n## Example\n\nImagine you have the following `model.swift` source code:\n\n```swift\n// Some demo code that will be analyzed by SourceKitten + the genum Swift script\n\nprotocol CasesEnumerable {}\n\nenum Boolish: Int, CasesEnumerable {\n  case Yeah = 1\n  case Nah = 0\n  case Meh = 2\n}\n\nstruct Deep {\n  enum Nested {\n    enum Key: CasesEnumerable {\n      case `public`\n      case `private`\n    }\n  }\n}\n\n//: FooClass\nclass Foo {\n\n  enum Direction: CasesEnumerable {\n    case north, south\n    case east\n    case west\n  }\n\n  enum Silent {\n    case does, not, conform, to, magic, proto\n    case so, wont, be, extended\n  }\n\n  enum CardSymbol: Character, CasesEnumerable {\n    case hearts = \"\\u{2661}\"\n    case spades = \"\\u{2664}\"\n    case clubs = \"\\u{2667}\"\n    case diamonds = \"\\u{2662}\"\n  }\n\n  func bar(value: String) -\u003e Int {\n    return 42\n  }\n}\n\n```\n\nThen running the command:\n\n```sh\nsourcekitten structure --file model.swift | generate-enum-allValues \u003eallValues.generated.swift\n```\n\nWill generate the following `allValues.generate.swift` output content:\n\n```swift\nextension Boolish {\n  static let allValues: [Boolish] = [.Yeah, .Nah, .Meh]\n}\nextension Deep.Nested.Key {\n  static let allValues: [Deep.Nested.Key] = [.public, .private]\n}\nextension Foo.Direction {\n  static let allValues: [Foo.Direction] = [.north, .south, .east, .west]\n}\nextension Foo.CardSymbol {\n  static let allValues: [Foo.CardSymbol] = [.hearts, .spades, .clubs, .diamonds]\n}\n```\n\nAnd thus you could then do some stuff like this elsewhere in your code:\n\n```swift\nprint(\"- Boolish         :\", Boolish.allValues.map { $0.rawValue })\nprint(\"- Deep.Nested.Key :\", Deep.Nested.Key.allValues)\nprint(\"- Foo.Direction   :\", Foo.Direction.allValues)\nprint(\"- Foo.CardSymbol  :\", Foo.CardSymbol.allValues.map { $0.rawValue })\n```\n\nSo that when you run your code, it will print:\n\n```\n- Boolish         : [1, 0, 2]\n- Deep.Nested.Key : [main.Deep.Nested.Key.public, main.Deep.Nested.Key.private]\n- Foo.Direction   : [main.Foo.Direction.north, main.Foo.Direction.south, main.Foo.Direction.east, main.Foo.Direction.west]\n- Foo.CardSymbol  : [\"♡\", \"♤\", \"♧\", \"♢\"]\n```\n\n\u003e You can find this example in the `./example` directory of that repo, and you can try it out using the `run_demo.sh` shell script (which invokes SourceKitten + the `generate-enum-allValues` Script, then `cat` everything in a single `swift` file to interpret and run it and print the values).\n\n\n---\n\n## Future Improvements ideas\n\n1. I hoped at first that this script would be able to use `SourceKittenFramework` (which happen to be included in SwiftLint so you probably already have it on your machine already) to parse the AST instead of requiring the user to invoke `sourcekitten structure` on the command line themselves.\nUnfortunately, I haven't succeeded in importing the Framework from the script as easily as I thought just yet.\n\n2. For this first version, I've decided to make this `allValues` generation opt-in, by only generating the extension for enums that are explicitly marked as `CasesEnumerable` directly. This is a deliberate choice, to avoid the risk of generating too much useless code if you were to generate `allValues` for all your enums even for those for which you don't need it\n\n  * I don't analyze the whole inheritance tree of the `enum`, just the list of its direct conformances, so `protocol Foo: CasesEnumerable` + `enum Bar: Foo` won't be matched\n  * The script could easily changed if you don't want this filtering and instead generate the `allValues` for _all_ the `enums` in your code. That's just a design choice.\n  * So in a future version maybe a command line flag or something could be added to allow the user to specify if they want to filter `enum` by a given protocol and even provide the protocol name themselves\n\n3. Every other interesting idea is welcome, don't hesitate to contribute. The script is quite small and all written in Swift, so it should be fairly easy to understand and contribute 😉\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falisoftware%2Fgenerate-enum-allvalues","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falisoftware%2Fgenerate-enum-allvalues","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falisoftware%2Fgenerate-enum-allvalues/lists"}