项目作者: JosephDuffy

项目描述 :
Add `Equatable` and/or `Hashable` conformance with a single function utilising `KeyPath`s.
高级语言: Swift
项目地址: git://github.com/JosephDuffy/HashableByKeyPath.git
创建时间: 2020-04-28T20:49:53Z
项目社区:https://github.com/JosephDuffy/HashableByKeyPath

开源协议:MIT License

下载


HashableByKeyPath

Tests

Code Coverage
Documentation
SwiftPM Compatible

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

  1. struct Foo: HashableKeyPathProvider {
  2. @HashableKeyPathCollectionBuilder<TestObject>
  3. static var hashableKeyPaths: HashableKeyPathCollection<Foo> {
  4. \Foo.bar1
  5. \Foo.bar2
  6. \Foo.bar3
  7. }
  8. var bar1: String
  9. var bar2: String
  10. var bar3: Int
  11. }
  12. let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
  13. let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
  14. let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
  15. let foos: Set = [foo1, foo2]
  16. foo1 == foo1 // true
  17. foo1 == foo2 // true
  18. foo1 == foo3 // false
  19. foo2 == foo3 // false
  20. foos.count // 1
  21. foos.contains(foo2) // true
  22. foos.contains(foo3) // false

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

  1. struct Foo: EquatableKeyPathProvider {
  2. @EquatableKeyPathCollectionBuilder<TestObject>
  3. static var equatableKeyPaths: EquatableKeyPathCollection<Foo> {
  4. \Foo.bar1
  5. \Foo.bar2
  6. \Foo.bar3
  7. }
  8. var bar1: String
  9. var bar2: String
  10. var bar3: Int
  11. }
  12. let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
  13. let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
  14. let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
  15. foo1 == foo1 // true
  16. foo1 == foo2 // true
  17. foo1 == foo3 // false
  18. 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:

  1. struct Foo: HashableByKeyPath {
  2. static func addHashableKeyPaths<Consumer: HashableKeyPathConsumer>(to consumer: inout Consumer) where Consumer.Root == Self {
  3. consumer.addHashableKeyPath(\.bar1)
  4. consumer.addHashableKeyPath(\.bar2)
  5. consumer.addHashableKeyPath(\.bar3)
  6. }
  7. var bar1: String
  8. var bar2: String
  9. var bar3: Int
  10. }
  11. let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
  12. let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
  13. let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
  14. let foos: Set = [foo1, foo2]
  15. foo1 == foo1 // true
  16. foo1 == foo2 // true
  17. foo1 == foo3 // false
  18. foo2 == foo3 // false
  19. foos.count // 1
  20. foos.contains(foo2) // true
  21. foos.contains(foo3) // false

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

  1. struct Foo: EquatableByKeyPath {
  2. static func addHashableKeyPaths<Consumer: HashableKeyPathConsumer>(to consumer: inout Consumer) where Consumer.Root == Self {
  3. consumer.addEquatableKeyPath(\.bar1)
  4. consumer.addEquatableKeyPath(\.bar2)
  5. consumer.addEquatableKeyPath(\.bar3)
  6. }
  7. var bar1: String
  8. var bar2: String
  9. var bar3: Int
  10. }
  11. let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
  12. let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
  13. let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
  14. foo1 == foo1 // true
  15. foo1 == foo2 // true
  16. foo1 == foo3 // false
  17. 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:

  1. let package = Package(
  2. ...
  3. dependencies: [
  4. .package(url: "https://github.com/JosephDuffy/HashableByKeyPath.git", from: "1.0.0"),
  5. ],
  6. targets: [
  7. .target(name: "MyApp", dependencies: ["HashableByKeyPath"]),
  8. ],
  9. ...
  10. )

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.