Skip to content

Commit b879ec6

Browse files
authored
Add rule to prefer a generated Equatable implementation when possible (#292)
1 parent 0b853e3 commit b879ec6

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ let package = Package(
4242

4343
.binaryTarget(
4444
name: "swiftformat",
45-
url: "https://github.com/calda/SwiftFormat/releases/download/0.55-beta-12/SwiftFormat.artifactbundle.zip",
46-
checksum: "8783cefc0837416759f81064df7907cc60ddca6d3f8c3b301b123a2193a8585b"),
45+
url: "https://github.com/calda/SwiftFormat/releases/download/0.55-beta-15/SwiftFormat.artifactbundle.zip",
46+
checksum: "5da82a61d4a29e77acc5a2e8668c40168970e1d6b2078bdfcb377b6f6ef35039"),
4747

4848
.binaryTarget(
4949
name: "SwiftLintBinary",

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3677,6 +3677,74 @@ _You can enable the following settings in Xcode by running [this script](resourc
36773677

36783678
</details>
36793679

3680+
* <a id='redundant-equatable-implementation'></a>(<a href='#redundant-equatable-implementation'>link</a>) **Prefer using a generated Equatable implementation when comparing all properties of a type.** For structs, prefer using the compiler-synthesized Equatable implementation when possible. [![SwiftFormat: redundantEquatable](https://img.shields.io/badge/SwiftFormat-redundantEquatable-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md#redundantEquatable)
3681+
3682+
<details>
3683+
3684+
### Why?
3685+
3686+
Manually-implemented Equatable implementations are verbose, and keeping them up-to-date is error-prone. For example, when adding a new property, it's possible to forget to update the Equatable implementation to compare it.
3687+
3688+
```swift
3689+
/// WRONG: The `static func ==` implementation is redundant and error-prone.
3690+
struct Planet: Equatable {
3691+
let mass: Double
3692+
let orbit: OrbitalElements
3693+
let rotation: Double
3694+
3695+
static func ==(lhs: Planet, rhs: Planet) -> Bool {
3696+
lhs.mass == rhs.mass
3697+
&& lhs.orbit == rhs.orbit
3698+
&& lhs.rotation == rhs.rotation
3699+
}
3700+
}
3701+
3702+
/// RIGHT: The `static func ==` implementation is synthesized by the compiler.
3703+
struct Planet: Equatable {
3704+
let mass: Double
3705+
let orbit: OrbitalElements
3706+
let rotation: Double
3707+
}
3708+
3709+
/// ALSO RIGHT: The `static func ==` implementation differs from the implementation that
3710+
/// would be synthesized by the compiler and compared all properties, so is not redundant.
3711+
struct CelestialBody: Equatable {
3712+
let id: UUID
3713+
let orbit: OrbitalElements
3714+
3715+
static func ==(lhs: Planet, rhs: Planet) -> Bool {
3716+
lhs.id == rhs.id
3717+
}
3718+
}
3719+
```
3720+
3721+
In projects that provide an `@Equatable` macro, prefer using that macro to generate the `static func ==` for classes rather than implementing it manually.
3722+
3723+
```swift
3724+
/// WRONG: The `static func ==` implementation is verbose and error-prone.
3725+
final class Planet: Equatable {
3726+
let mass: Double
3727+
let orbit: OrbitalElements
3728+
let rotation: Double
3729+
3730+
static func ==(lhs: Planet, rhs: Planet) -> Bool {
3731+
lhs.mass == rhs.mass
3732+
&& lhs.orbit == rhs.orbit
3733+
&& lhs.rotation == rhs.rotation
3734+
}
3735+
}
3736+
3737+
/// RIGHT: The `static func ==` implementation is generated by the `@Equatable` macro.
3738+
@Equatable
3739+
final class struct Planet: Equatable {
3740+
let mass: Double
3741+
let orbit: OrbitalElements
3742+
let rotation: Double
3743+
}
3744+
```
3745+
3746+
</details>
3747+
36803748
* <a id='void-type'></a>(<a href='#void-type'>link</a>) **Avoid using `()` as a type**. Prefer `Void`.
36813749

36823750
<details>

Sources/AirbnbSwiftFormatTool/airbnb.swiftformat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
--rules redundantGet
6868
--rules redundantFileprivate
6969
--rules redundantRawValues
70+
--rules redundantEquatable
7071
--rules sortImports
7172
--rules sortDeclarations
7273
--rules strongifiedSelf

0 commit comments

Comments
 (0)