Created
January 7, 2020 02:37
-
-
Save omochi/b68706b90134db8c3771195da170d4b5 to your computer and use it in GitHub Desktop.
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
// see also https://gist.github.com/tarunon/85bdeccf8bc8f44b7b27d4974e0a843f | |
// user interface | |
public protocol MaybeEquatable { | |
func eraseToOpaqueEquatable() -> ErasedOpaqueEquatable | |
} | |
extension MaybeEquatable { | |
public func isEqual(to other: Any) -> Bool { | |
eraseToOpaqueEquatable().isEqual(to: other) | |
} | |
} | |
extension MaybeEquatable { | |
public func eraseToOpaqueEquatable() -> ErasedOpaqueEquatable { | |
ErasedOpaqueEquatable() | |
} | |
} | |
extension MaybeEquatable where Self: Equatable { | |
public func eraseToOpaqueEquatable() -> ErasedOpaqueEquatable { | |
TypedOpaqueEquatable(self) | |
} | |
} | |
public class ErasedOpaqueEquatable { | |
internal func isEqual(to other: Any) -> Bool { | |
false | |
} | |
} | |
internal final class TypedOpaqueEquatable<T: Equatable>: ErasedOpaqueEquatable { | |
private var left: T | |
internal init(_ left: T) { | |
self.left = left | |
} | |
internal override func isEqual(to right: Any) -> Bool { | |
guard let right = right as? T else { return false } | |
return left == right | |
} | |
} | |
// end user interface | |
func anyIsEqual(_ a: Any, _ b: Any) -> Bool { | |
guard let a = a as? MaybeEquatable else { return false } | |
return a.isEqual(to: b) | |
} | |
// you need to mark your type | |
extension String: MaybeEquatable {} | |
print(anyIsEqual("str", "str")) // => true | |
print(anyIsEqual({}, {})) // => false |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment