diff --git a/Sources/Identity/Identity.swift b/Sources/Identity/Identity.swift index 1e2b759..309f30d 100644 --- a/Sources/Identity/Identity.swift +++ b/Sources/Identity/Identity.swift @@ -77,10 +77,18 @@ extension Identifier: CustomStringConvertible { } } +// MARK: - Hashable support + +extension Identifier: Hashable where Value.RawIdentifier: Hashable { + public func hash(into hasher: inout Hasher) { + hasher.combine(ObjectIdentifier(Value.self)) + hasher.combine(rawValue) + } +} + // MARK: - Compiler-generated protocol support extension Identifier: Equatable where Value.RawIdentifier: Equatable {} -extension Identifier: Hashable where Value.RawIdentifier: Hashable {} // MARK: - Codable support diff --git a/Tests/IdentityTests/IdentityTests.swift b/Tests/IdentityTests/IdentityTests.swift index da61bc1..018ba4b 100644 --- a/Tests/IdentityTests/IdentityTests.swift +++ b/Tests/IdentityTests/IdentityTests.swift @@ -76,6 +76,21 @@ final class IdentityTests: XCTestCase { XCTAssertEqual(intID.description, "7") } + func testIdentifierHashValue() { + struct FirstModel: Identifiable { + let id: ID + } + + struct SecondModel: Identifiable { + let id: ID + } + + let first = FirstModel(id: "0") + let second = SecondModel(id: "0") + + XCTAssertNotEqual(first.id.hashValue, second.id.hashValue) + } + func testAllTestsRunOnLinux() { verifyAllTestsRunOnLinux() } @@ -88,6 +103,7 @@ extension IdentityTests: LinuxTestable { ("testCodableIdentifier", testCodableIdentifier), ("testIdentifierEncodedAsSingleValue", testIdentifierEncodedAsSingleValue), ("testExpressingIdentifierUsingStringInterpolation", testExpressingIdentifierUsingStringInterpolation), - ("testIdentifierDescription", testIdentifierDescription) + ("testIdentifierDescription", testIdentifierDescription), + ("testIdentifierHashValue", testIdentifierHashValue), ] }