Created
March 1, 2018 11:17
-
-
Save werner-freytag/e4f1fdcd201db1cdc726f6d81d55aa18 to your computer and use it in GitHub Desktop.
Allow any protocol to conform to Equatable using a wrapper
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
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