Skip to content

Commit

Permalink
Add rule to always inline let keyword when destructuring enum cases a…
Browse files Browse the repository at this point in the history
…nd tuples (#126)
  • Loading branch information
calda authored May 21, 2021
1 parent ffe5acd commit 5ac3493
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,59 @@ _You can enable the following settings in Xcode by running [this script](resourc

</details>

* <a id='inline-let-when-destructuring'></a> (<a href='#inline-let-when-destructuring'>link</a>) **When destructuring an enum case or a tuple, place the `let` keyword inline, adjacent to each individual property assignment.** [![SwiftFormat: hoistPatternLet](https://img.shields.io/badge/SwiftFormat-hoistPatternLet-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md#hoistPatternLet)

<details>

```swift
// WRONG
switch result {
case let .success(value):
// ...
case let .error(errorCode, errorReason):
// ...
}

// WRONG
guard let case .success(value) else {
return
}

// RIGHT
switch result {
case .success(let value):
// ...
case .error(let errorCode, let errorReason):
// ...
}

// RIGHT
guard case .success(let value) else {
return
}
```

#### Why?

1. **Consistency**: We should prefer to either _always_ inline the `let` keyworkd or _never_ inline the `let` keyword. In Airbnb's Swift codebase, we [observed](https://github.com/airbnb/swift/pull/126#discussion_r631979244) that inline `let` is used far more often in practice (especially when destructuring enum cases with a single associated value).

2. **Clarity**: Inlining the `let` keyword makes it more clear which identifiers are part of the conditional check and which identifiers are binding new variables, since the `let` keyword is always adjacent to the variable identifier.

```swift
// `let` is adjacent to the variable identifier, so it is immediately obvious
// at a glance that these identifiers represent new variable bindings
case .enumCaseWithSingleAssociatedValue(let string):
case .enumCaseWithMultipleAssociatedValues(let string, let int):

// The `let` keyword is quite far from the variable identifiers,
// so its less obvious that they represent new variable bindings
case let .enumCaseWithSingleAssociatedValue(string):
case let .enumCaseWithMultipleAssociatedValues(string, int):

```

</details>

* <a id='attributes-on-prev-line'></a>(<a href='#attributes-on-prev-line'>link</a>) **Place function/type attributes on the line above the declaration**. [![SwiftFormat: wrapAttributes](https://img.shields.io/badge/SwiftFormat-wrapAttributes-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md#wrapAttributes)

<details>
Expand Down
3 changes: 2 additions & 1 deletion resources/airbnb.swiftformat
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
--enumthreshold 20 # organizeDeclarations
--organizetypes class,struct,enum,extension # organizeDeclarations
--extensionacl on-declarations # extensionAccessControl
--patternlet inline # hoistPatternLet
--swiftversion 5.1

# rules
--rules anyObjectProtocol,redundantParens,redundantReturn,redundantSelf,sortedImports,strongifiedSelf,trailingCommas,trailingSpace,wrapArguments,wrapMultilineStatementBraces,indent,wrapAttributes,organizeDeclarations,markTypes,extensionAccessControl,duplicateImports,redundantType,consecutiveSpaces
--rules anyObjectProtocol,redundantParens,redundantReturn,redundantSelf,sortedImports,strongifiedSelf,trailingCommas,trailingSpace,wrapArguments,wrapMultilineStatementBraces,indent,wrapAttributes,organizeDeclarations,markTypes,extensionAccessControl,duplicateImports,redundantType,hoistPatternLet,consecutiveSpaces

0 comments on commit 5ac3493

Please sign in to comment.