Swiftpack.co - JosephDuffy/HashableByKeyPath as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
JosephDuffy/HashableByKeyPath v1.2.0-beta.2
Add `Equatable` and/or `Hashable` conformance with a single function utilising `KeyPath`s.
⭐️ 7
🕓 2 days ago
.package(url: "https://github.com/JosephDuffy/HashableByKeyPath.git", from: "v1.2.0-beta.2")

HashableByKeyPath

Tests Supported Xcode Versions Code Coverage Documentation SwiftPM Compatible

HashableByKeyPath helps avoid common mistakes when implementing Hashable and Equatable conformance:

struct Foo: HashableKeyPathProvider {
    @HashableKeyPathCollectionBuilder<TestObject>
    static var hashableKeyPaths: HashableKeyPathCollection<Foo> {
        \Foo.bar1
        \Foo.bar2
        \Foo.bar3
    }

    var bar1: String
    var bar2: String
    var bar3: Int
}

let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
let foos: Set = [foo1, foo2]

foo1 == foo1 // true
foo1 == foo2 // true
foo1 == foo3 // false
foo2 == foo3 // false
foos.count // 1
foos.contains(foo2) // true
foos.contains(foo3) // false

If the type only needs to conform to Equatable the type can conform to EquatableByKeyPath:

struct Foo: EquatableKeyPathProvider {
    @EquatableKeyPathCollectionBuilder<TestObject>
    static var equatableKeyPaths: EquatableKeyPathCollection<Foo> {
        \Foo.bar1
        \Foo.bar2
        \Foo.bar3
    }

    var bar1: String
    var bar2: String
    var bar3: Int
}

let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")

foo1 == foo1 // true
foo1 == foo2 // true
foo1 == foo3 // false
foo2 == foo3 // false

When using a non-final class the HashableKeyPathProvider and EquatableKeyPathProvider protocols cannot be used. In this case the HashableByKeyPath and EquatableByKeyPath protocols should be used:

struct Foo: HashableByKeyPath {
    static func addHashableKeyPaths<Consumer: HashableKeyPathConsumer>(to consumer: inout Consumer) where Consumer.Root == Self {
        consumer.addHashableKeyPath(\.bar1)
        consumer.addHashableKeyPath(\.bar2)
        consumer.addHashableKeyPath(\.bar3)
    }

    var bar1: String
    var bar2: String
    var bar3: Int
}

let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
let foos: Set = [foo1, foo2]

foo1 == foo1 // true
foo1 == foo2 // true
foo1 == foo3 // false
foo2 == foo3 // false
foos.count // 1
foos.contains(foo2) // true
foos.contains(foo3) // false

If the type only needs to conform to Equatable the type can conform to EquatableByKeyPath:

struct Foo: EquatableByKeyPath {
    static func addHashableKeyPaths<Consumer: HashableKeyPathConsumer>(to consumer: inout Consumer) where Consumer.Root == Self {
        consumer.addEquatableKeyPath(\.bar1)
        consumer.addEquatableKeyPath(\.bar2)
        consumer.addEquatableKeyPath(\.bar3)
    }

    var bar1: String
    var bar2: String
    var bar3: Int
}

let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")

foo1 == foo1 // true
foo1 == foo2 // true
foo1 == foo3 // false
foo2 == foo3 // false

Installation

HashableByKeyPath supports installation via SwiftPM. This can be done by adding the package to the dependencies section and as the dependency of a target:

let package = Package(
    ...
    dependencies: [
        .package(url: "https://github.com/JosephDuffy/HashableByKeyPath.git", from: "1.0.0"),
    ],
    targets: [
        .target(name: "MyApp", dependencies: ["HashableByKeyPath"]),
    ],
    ...
)

Documentation

HashableByKeyPath is fully documented, with code-level documentation available online. The online documentation is generated from the source code with every release, so it is up-to-date with the latest release, but may be different to the code in master.

Tests and CI

HashableByKeyPath has a full test suite, which is run on GitHub actions as part of pull requests. All tests must pass for a pull request to be merged.

Code coverage is collected and reported to to Codecov.

License

The project is released under the MIT license. View the LICENSE file for the full license.

GitHub

link
Stars: 7
Last commit: 2 days ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Submit a free job ad (while I'm testing this). The analytics numbers for this website are here.

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics