I have several different enums in my project, that conform to the same protocol. The compareEnumType method from the protocol compares enum cases ignoring associated values. Here is my code from playground:
protocol EquatableEnumType {
static func compareEnumType(lhs: Self, rhs: Self) -> Bool
}
enum MyEnum: EquatableEnumType {
case A(Int)
case B
static func compareEnumType(lhs: MyEnum, rhs: MyEnum) -> Bool {
switch (lhs, rhs) {
case (.A, .A): return true
case (.B, .B): return true
default: return false
}
}
}
enum MyEnum2: EquatableEnumType {
case X(String)
case Y
static func compareEnumType(lhs: MyEnum2, rhs: MyEnum2) -> Bool {
switch (lhs, rhs) {
case (.X, .X): return true
case (.Y, .Y): return true
default: return false
}
}
}
let a = MyEnum.A(5)
let a1 = MyEnum.A(3)
if MyEnum.compareEnumType(lhs: a, rhs: a1) {
print("equal") // -> true, prints "equal"
}
let x = MyEnum2.X("table")
let x1 = MyEnum2.X("chair")
if MyEnum2.compareEnumType(lhs: x, rhs: x1) {
print("equal2") // -> true, prints "equal2"
}
In my real project I have more than 2 enums, and for each of them I have to have similar implementation of compareEnumType function.
The question is: is it possible to have a generic implementation of compareEnumType which would work for all enums conforming to EquatableEnumType protocol?
I tried to write a default implementation in protocol extension like this:
extension EquatableEnumType {
static func compareEnumType(lhs: Self, rhs: Self) -> Bool {
// how to implement???
}
}
But I'm stuck with implementation. I don't see a way to access a value contained in lhs and rhs. Could anyone help me?
Equatable, which "implies substitutability—any two instances that compare equally can be used interchangeably in any code that depends on their values. To maintain substitutability, the == operator should take into account all visible aspects of an Equatable type. Exposing nonvalue aspects of Equatable types other than class identity is discouraged, and any that are exposed should be explicitly pointed out in documentation." This is a very bad idea, and you should redesign your types to avoid it. If you are determined to do this, the tool you'll need is SwiftGen. - Rob Napier