I was using CaseIterable to iterate through the enum options and came up with a case that would be nice to solve.
I was attempting to use a nested enum that also conformed to CaseIterable - I don't see any reason why the outer Example enum cannot create a union of it's nested children
enum Example: CaseIterable {
case a(A), b, c
}
enum A: CaseIterable {
case d, e, f
}
To work around it you can provide manual conformance:
extension Example {
static var allCases: [Example] {
[b, c] + A.allCases.map(Example.a)
}
}
Hi. I agree that it is strange when two CaseIterable enums loose the ability to be CaseIterable when compounded. But can you please provide some real world examples?
Because "I don't see any reason why the outer Example enum cannot create a union of it's nested children" is not enough motivation.
Some real-world use-cases can include navigation routing and theming, though, I haven't explored more scenarios then that - I am sure there will be lots more
If you want some specific code examples I can share some from my recent work looking into Composable Architecture and defining composable routes using a NavigationLink
enum HomeRoute: CaseIterable, NavigationRoute {
case music(MusicRoute)
case settings(SettingsRoute)
func destination(in: Store<_, _>) -> some View
}
enum MusicRoute: CaseIterable, NavigationRoute {
case song
case album
func destination(in: Store<_, _>) -> some View
}
enum SettingsRoute: CaseIterable, NavigationRoute {
case user
case app
func destination(in: Store<_, _>) -> some View
}
In the example above, I would require access to the cases to configure the navigation links ahead of time so when you come to perform the action of navigating they are already available in the SwiftUI view hierarchy
Thanks for sharing. In my practice I can only find one case. To point out, CaseIterable is needed only as a help feature for writing exhaustive list of test cases. Here is simplified example:
enum DeliveryKind {
case addressDelivery
case pickupPoint(kind: PickupPointDeliveryKind)
case express(kind : ExpressDeliveryKind)
enum PickupPointDeliveryKind {
case shop
case post
}
enum ExpressDeliveryKind {
case courier
case taxi
}
}
DeliveryTests: XCTest {
for deliveryKind in DeliveryKind.allCases {
// test some feature
}
}
It will be good to hear from the community other cases, examples and arguments. Seems it is rather simple to implement it in the compiler.
It would be totally reasonable to support this; we didn't include it in the proposal because (a) we wanted to keep the design and implementation small and simple, and (b) various other reasons that don't really apply anymore.
Specifically...
(a) it wasn't clear how much we wanted to focus on enum cases vs. other small iterable types like `Bool` or `Int8`; (b) we were thinking at the time that the default implementation of `allCases` might not return an `Array`, but instead a custom collection that generated the cases lazily, which would be hard to do with associated values; (c) we were trying to strip out unnecessary "bells and whistles" to get to a core proposal that everyone agreed with and thought was justified.
So this would definitely be a natural extension of CaseIterable; the question is mainly if it's worth the trouble. You might want to dig through SE-0194's review and discussion threads to see if there are any points for or against that I've forgotten in the last three-ish years.