Skip to content

Instantly share code, notes, and snippets.

@werner-freytag
Created March 1, 2018 11:17
Show Gist options
  • Save werner-freytag/e4f1fdcd201db1cdc726f6d81d55aa18 to your computer and use it in GitHub Desktop.
Save werner-freytag/e4f1fdcd201db1cdc726f6d81d55aa18 to your computer and use it in GitHub Desktop.
Allow any protocol to conform to Equatable using a wrapper
import Foundation
protocol AnyEquatableWrappable {
func isEqualTo(_ other: AnyEquatableWrappable) -> Bool
var asEquatable: AnyEquatable { get }
}
extension AnyEquatableWrappable where Self: Equatable {
func isEqualTo(_ other: AnyEquatableWrappable) -> Bool {
guard let other = other as? Self else { return false }
return self == other
}
var asEquatable: AnyEquatable {
return AnyEquatable(self)
}
}
struct AnyEquatable {
init(_ object: AnyEquatableWrappable) {
self.object = object
}
fileprivate let object: AnyEquatableWrappable
}
extension AnyEquatable: Equatable {
static func ==(lhs: AnyEquatable, rhs: AnyEquatable) -> Bool {
return lhs.object.isEqualTo(rhs.object)
}
}
// Exampe:
struct Apple {
let weight: Int
let grade: Int
}
struct Orange {
let weight: Int
let grade: Int
}
extension Apple: AnyEquatableWrappable {}
extension Orange: AnyEquatableWrappable {}
extension Apple: Equatable {
static func ==(lhs: Apple, rhs: Apple) -> Bool {
return lhs.weight == rhs.weight && lhs.grade == rhs.grade
}
}
extension Orange: Equatable {
static func ==(lhs: Orange, rhs: Orange) -> Bool {
return lhs.weight == rhs.weight && lhs.grade == rhs.grade
}
}
let apple = Apple(weight: 10, grade: 2)
let orange = Orange(weight: 10, grade: 2)
print(apple.asEquatable == orange.asEquatable)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment