Created
September 23, 2019 15:01
-
-
Save T1T4N/e5d75a6c422d9fd8c2e0fa7984017408 to your computer and use it in GitHub Desktop.
Enums with Associated Values: Protocol & example implementation of matching without taking the associated value into account
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol CaseEquatable { | |
associatedtype Case: Equatable | |
var `case`: Case { get } | |
static func ~=(lhs: Self, rhs: Self) -> Bool | |
} | |
extension CaseEquatable { | |
static func ~=(lhs: Self, rhs: Self) -> Bool { | |
return lhs.case == rhs.case | |
} | |
} | |
extension CaseEquatable { | |
static func ~=(lhs: Self, rhs: Self.Case) -> Bool { | |
return lhs.case == rhs | |
} | |
static func ~=(lhs: Self.Case, rhs: Self) -> Bool { | |
return lhs == rhs.case | |
} | |
} | |
// MARK: - Example enum implementation | |
enum DetailPage: Hashable, CaseIterable { | |
case basic, advanced | |
} | |
enum Screen: Hashable { | |
case fetch | |
case detail(DetailPage = .basic) | |
} | |
extension Screen: CaseEquatable { | |
// Workaround for comparing enum cases without associated values | |
// Which is fully supported & possible using | |
// switch/if case, but not ternary operator/pattern matching | |
// https://forums.swift.org/t/operator-for-enums-with-ignored-associated-values/23481/2 | |
// Hope this gets added as a language feature so that it's auto-synthesized | |
enum Case: String, Identifiable, CaseIterable { | |
case fetch, detail | |
} | |
var `case`: Case { | |
switch self { | |
case .fetch: return .fetch | |
case .detail: return .detail | |
} | |
} | |
} | |
extension Screen { | |
public static func screen(for screenCase: Screen.Case) -> Screen { | |
switch screenCase { | |
case .fetch: return .fetch | |
case .detail: return .detail() // default page value | |
} | |
} | |
} | |
extension Screen: CaseIterable { | |
static let allCases: [Feature] = | |
[.fetch] + DetailPage.allCases.map(Feature.detail) | |
} | |
// Matching a case while discarding the associated value | |
// let screen: Screen = .detail(.advanced) | |
// screen ~= .detail |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment