Skip to content

Commit 2bcd85a

Browse files
KSXGitHubclaude
andauthored
docs(dev/guide): align guides with enforced perfectionist rules (#434)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent de2d681 commit 2bcd85a

5 files changed

Lines changed: 13 additions & 23 deletions

File tree

.github/copilot-instructions.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
77
- Commit format: Conventional Commits. Pattern: `type(scope): lowercase description`. The scope is optional.
88
- Version releases are the only exception. The commit message is just the version number, such as `0.21.1`.
99
- Write documentation, comments, and other prose for ease of understanding first. Prefer a formal tone when it does not hurt clarity, and use complete sentences. Avoid mid-sentence breaks introduced by em dashes or long parenthetical clauses. Em dashes are a reliable symptom of loose phrasing; when one appears, restructure the surrounding sentence so each clause stands on its own rather than swapping the em dash for another punctuation mark.
10-
- Prefer imports merged per module. Combine items from the same module into a single `use` statement, but write a separate `use` statement for each module rather than collapsing every path from a crate into one nested-braces statement.
1110
- Use descriptive names for generics, such as `Size` and `Report`. Do not use single letters.
12-
- Use descriptive names for variables and closure parameters. Single letters are permitted only in these cases: (1) conventional names like `n` for count or `f` for formatter; (2) comparison closures like `|a, b|`; (3) trivial single-expression closures; (4) fold accumulators; (5) index variables `i`/`j`/`k` in short closures or index-based loops; and (6) test fixtures with identical roles. Single letters are never permitted in multi-line functions or closures.
11+
- Use descriptive names for variables and closure parameters. Single letters are permitted only in these cases: (1) conventional names like `n` for count or `f` for formatter; (2) comparison closures like `|a, b|`; (3) trivial single-expression closures; (4) fold accumulators; and (5) index variables `i`/`j`/`k` in short closures or index-based loops. Single letters are never permitted in `let` bindings, including test fixtures, nor in multi-line functions or closures.
1312
- Use `pipe-trait` to chain through unary functions such as constructors, `Some`, `Ok`, and free functions. Use it to flatten nested calls and to continue method chains. Do not use it for simple standalone calls; prefer `foo(value)` over `value.pipe(foo)`.
1413
- Prefer `where` clauses when a type has multiple trait bounds.
1514
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.

AGENTS.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
77
- Commit format: Conventional Commits. Pattern: `type(scope): lowercase description`. The scope is optional.
88
- Version releases are the only exception. The commit message is just the version number, such as `0.21.1`.
99
- Write documentation, comments, and other prose for ease of understanding first. Prefer a formal tone when it does not hurt clarity, and use complete sentences. Avoid mid-sentence breaks introduced by em dashes or long parenthetical clauses. Em dashes are a reliable symptom of loose phrasing; when one appears, restructure the surrounding sentence so each clause stands on its own rather than swapping the em dash for another punctuation mark.
10-
- Prefer imports merged per module. Combine items from the same module into a single `use` statement, but write a separate `use` statement for each module rather than collapsing every path from a crate into one nested-braces statement.
1110
- Use descriptive names for generics, such as `Size` and `Report`. Do not use single letters.
12-
- Use descriptive names for variables and closure parameters. Single letters are permitted only in these cases: (1) conventional names like `n` for count or `f` for formatter; (2) comparison closures like `|a, b|`; (3) trivial single-expression closures; (4) fold accumulators; (5) index variables `i`/`j`/`k` in short closures or index-based loops; and (6) test fixtures with identical roles. Single letters are never permitted in multi-line functions or closures.
11+
- Use descriptive names for variables and closure parameters. Single letters are permitted only in these cases: (1) conventional names like `n` for count or `f` for formatter; (2) comparison closures like `|a, b|`; (3) trivial single-expression closures; (4) fold accumulators; and (5) index variables `i`/`j`/`k` in short closures or index-based loops. Single letters are never permitted in `let` bindings, including test fixtures, nor in multi-line functions or closures.
1312
- Use `pipe-trait` to chain through unary functions such as constructors, `Some`, `Ok`, and free functions. Use it to flatten nested calls and to continue method chains. Do not use it for simple standalone calls; prefer `foo(value)` over `value.pipe(foo)`.
1413
- Prefer `where` clauses when a type has multiple trait bounds.
1514
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.

CLAUDE.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
77
- Commit format: Conventional Commits. Pattern: `type(scope): lowercase description`. The scope is optional.
88
- Version releases are the only exception. The commit message is just the version number, such as `0.21.1`.
99
- Write documentation, comments, and other prose for ease of understanding first. Prefer a formal tone when it does not hurt clarity, and use complete sentences. Avoid mid-sentence breaks introduced by em dashes or long parenthetical clauses. Em dashes are a reliable symptom of loose phrasing; when one appears, restructure the surrounding sentence so each clause stands on its own rather than swapping the em dash for another punctuation mark.
10-
- Prefer imports merged per module. Combine items from the same module into a single `use` statement, but write a separate `use` statement for each module rather than collapsing every path from a crate into one nested-braces statement.
1110
- Use descriptive names for generics, such as `Size` and `Report`. Do not use single letters.
12-
- Use descriptive names for variables and closure parameters. Single letters are permitted only in these cases: (1) conventional names like `n` for count or `f` for formatter; (2) comparison closures like `|a, b|`; (3) trivial single-expression closures; (4) fold accumulators; (5) index variables `i`/`j`/`k` in short closures or index-based loops; and (6) test fixtures with identical roles. Single letters are never permitted in multi-line functions or closures.
11+
- Use descriptive names for variables and closure parameters. Single letters are permitted only in these cases: (1) conventional names like `n` for count or `f` for formatter; (2) comparison closures like `|a, b|`; (3) trivial single-expression closures; (4) fold accumulators; and (5) index variables `i`/`j`/`k` in short closures or index-based loops. Single letters are never permitted in `let` bindings, including test fixtures, nor in multi-line functions or closures.
1312
- Use `pipe-trait` to chain through unary functions such as constructors, `Some`, `Ok`, and free functions. Use it to flatten nested calls and to continue method chains. Do not use it for simple standalone calls; prefer `foo(value)` over `value.pipe(foo)`.
1413
- Prefer `where` clauses when a type has multiple trait bounds.
1514
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.

CONTRIBUTING.md

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ Automated tools enforce formatting (`cargo fmt`), linting (`cargo clippy`), and
3636

3737
### Import Organization
3838

39-
Prefer **merged imports** at module granularity. Combine multiple items from the same module into a single `use` statement with braces, but write a separate `use` statement for each module rather than collapsing every path from a crate into one nested-braces statement. This granularity is enforced by the `perfectionist::import_granularity` dylint check (`style = "module"`). Import ordering is enforced by `cargo fmt`. Imports gated by a platform attribute such as `#[cfg(unix)]` go in a separate block after the main imports.
39+
Import granularity is enforced automatically by the `perfectionist::import_granularity` rule, configured for the `module` style. Items from the same module are merged into a single braced `use` statement, while each module keeps its own `use` statement rather than collapsing an entire crate into one nested-braces statement. Import ordering is enforced separately by `cargo fmt`.
40+
41+
The remaining convention is not enforced and must be applied by hand. Imports gated by a platform attribute such as `#[cfg(unix)]` go in a separate block after the main imports.
4042

4143
```rust
4244
use crate::args::{Args, Quantity, Threads};
@@ -87,11 +89,11 @@ Use **descriptive names** for type parameters, not single letters:
8789

8890
- `Size`, `Name`, `SizeGetter`, `HardlinksRecorder`, `Report`
8991

90-
Single-letter generics are acceptable only in very short, self-contained trait impls. Enforced by `perfectionist::single_letter_generic`; the threshold for "very short" is the rule's `short_impl_max_lines` knob in `dylint.toml`.
92+
Single-letter type parameters are flagged by `perfectionist::single_letter_generic`.
9193

9294
### Variable and Closure Parameter Naming
9395

94-
Use **descriptive names** for variables and closure parameters by default. Single-letter names are permitted only in the specific cases listed below. Enforced by `perfectionist::single_letter_let_binding`, `perfectionist::single_letter_function_param`, and `perfectionist::single_letter_closure_param`; the per-rule `allowed_idents` and `extra_trivial_callback_methods` knobs in `dylint.toml` reflect the exceptions documented here.
96+
Use **descriptive names** for variables and closure parameters by default. Single-letter names are permitted only in the specific cases listed below. Enforced by `perfectionist::single_letter_let_binding`, `perfectionist::single_letter_function_param`, and `perfectionist::single_letter_closure_param`. The exact exemptions differ by binding kind, as the cases below describe. The `extra_allowed_idents` and `extra_trivial_callback_methods` knobs in `dylint.toml` extend the built-in exempt sets, though the project currently relies on the defaults aside from the `sort_reflection_by` callback.
9597

9698
#### When single-letter names are allowed
9799

@@ -108,16 +110,16 @@ Use **descriptive names** for variables and closure parameters by default. Singl
108110
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { todo!() }
109111
```
110112

111-
- **Index variables (`i`, `j`, `k`):** These may only be used in two contexts: short closures, and index-based loops or iterations. The latter is rare in Rust. In all other cases, use `index`, `idx`, or `*_index`.
113+
- **Index variables (`i`, `j`, `k`):** These are exempt as function and closure parameters, and they read naturally in index-based loops or iterations, which are rare in Rust. They are not exempt as `let` bindings, where only `n` is allowed, so a `let` that holds an index must use `index`, `idx`, or `*_index` instead.
112114

113115
```rust
114-
// OK: short closure
116+
// OK: closure parameter
115117
left_indices.zip(right_indices).map(|(i, j)| matrix[i][j])
116118

117119
// OK: index-based loop
118120
for i in 0..len { /* ... */ }
119121

120-
// Bad: use a descriptive name instead
122+
// Bad: a `let` binding allows only `n`, never `i`
121123
let i = items.iter().position(|item| item.is_active()).unwrap();
122124
```
123125

@@ -133,14 +135,6 @@ Use **descriptive names** for variables and closure parameters by default. Singl
133135
.fold(PathBuf::new(), |acc, x| acc.join(x))
134136
```
135137

136-
- **Test fixtures:** `let a`, `let b`, `let c` for interchangeable specimens with identical roles in equality or comparison tests. Do not use single letters when the variables have distinct roles; use `actual`/`expected` or similar descriptive names instead.
137-
138-
```rust
139-
let a = vec![3, 1, 2].into_iter().collect::<BTreeSet<_>>();
140-
let b = vec![2, 3, 1].into_iter().collect::<BTreeSet<_>>();
141-
assert_eq!(a, b);
142-
```
143-
144138
#### When single-letter names are NOT allowed
145139

146140
- **Multi-line functions and closures:** Use a descriptive name when a function or closure body spans multiple lines. Examples include a body that contains a `let` binding followed by another expression, or a body with multiple chained operations.
@@ -159,7 +153,7 @@ Use **descriptive names** for variables and closure parameters by default. Singl
159153
})
160154
```
161155

162-
- **`let` bindings in non-test code:** Always use descriptive names.
156+
- **`let` bindings:** Always use descriptive names.
163157

164158
```rust
165159
// Good

template/ai-instructions/shared.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
77
- Commit format: Conventional Commits. Pattern: `type(scope): lowercase description`. The scope is optional.
88
- Version releases are the only exception. The commit message is just the version number, such as `0.21.1`.
99
- Write documentation, comments, and other prose for ease of understanding first. Prefer a formal tone when it does not hurt clarity, and use complete sentences. Avoid mid-sentence breaks introduced by em dashes or long parenthetical clauses. Em dashes are a reliable symptom of loose phrasing; when one appears, restructure the surrounding sentence so each clause stands on its own rather than swapping the em dash for another punctuation mark.
10-
- Prefer imports merged per module. Combine items from the same module into a single `use` statement, but write a separate `use` statement for each module rather than collapsing every path from a crate into one nested-braces statement.
1110
- Use descriptive names for generics, such as `Size` and `Report`. Do not use single letters.
12-
- Use descriptive names for variables and closure parameters. Single letters are permitted only in these cases: (1) conventional names like `n` for count or `f` for formatter; (2) comparison closures like `|a, b|`; (3) trivial single-expression closures; (4) fold accumulators; (5) index variables `i`/`j`/`k` in short closures or index-based loops; and (6) test fixtures with identical roles. Single letters are never permitted in multi-line functions or closures.
11+
- Use descriptive names for variables and closure parameters. Single letters are permitted only in these cases: (1) conventional names like `n` for count or `f` for formatter; (2) comparison closures like `|a, b|`; (3) trivial single-expression closures; (4) fold accumulators; and (5) index variables `i`/`j`/`k` in short closures or index-based loops. Single letters are never permitted in `let` bindings, including test fixtures, nor in multi-line functions or closures.
1312
- Use `pipe-trait` to chain through unary functions such as constructors, `Some`, `Ok`, and free functions. Use it to flatten nested calls and to continue method chains. Do not use it for simple standalone calls; prefer `foo(value)` over `value.pipe(foo)`.
1413
- Prefer `where` clauses when a type has multiple trait bounds.
1514
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.

0 commit comments

Comments
 (0)