Skip to content

Instantly share code, notes, and snippets.

@omochi
Created January 7, 2020 02:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omochi/b68706b90134db8c3771195da170d4b5 to your computer and use it in GitHub Desktop.
Save omochi/b68706b90134db8c3771195da170d4b5 to your computer and use it in GitHub Desktop.
// 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