Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- Use descriptive names for generics, such as `Size` and `Report`. Do not use single letters.
- 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.
- 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)`.
- In test code, use the `command-extra` crate (the `CommandExtra` trait) when building `std::process::Command`. Call `.with_arg(...)`, `.with_env(...)`, `.without_env(...)`, `.with_no_env()`, and similar methods rather than `.arg(...)`, `.env(...)`, `.env_remove(...)`, and `.env_clear()`, so construction remains a single owned expression chain.
- Prefer `where` clauses when a type has multiple trait bounds.
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.
- Minimize `unwrap()` in non-test code. Use proper error handling instead.
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- Use descriptive names for generics, such as `Size` and `Report`. Do not use single letters.
- 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.
- 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)`.
- In test code, use the `command-extra` crate (the `CommandExtra` trait) when building `std::process::Command`. Call `.with_arg(...)`, `.with_env(...)`, `.without_env(...)`, `.with_no_env()`, and similar methods rather than `.arg(...)`, `.env(...)`, `.env_remove(...)`, and `.env_clear()`, so construction remains a single owned expression chain.
- Prefer `where` clauses when a type has multiple trait bounds.
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.
- Minimize `unwrap()` in non-test code. Use proper error handling instead.
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- Use descriptive names for generics, such as `Size` and `Report`. Do not use single letters.
- 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.
- 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)`.
- In test code, use the `command-extra` crate (the `CommandExtra` trait) when building `std::process::Command`. Call `.with_arg(...)`, `.with_env(...)`, `.without_env(...)`, `.with_no_env()`, and similar methods rather than `.arg(...)`, `.env(...)`, `.env_remove(...)`, and `.env_clear()`, so construction remains a single owned expression chain.
- Prefer `where` clauses when a type has multiple trait bounds.
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.
- Minimize `unwrap()` in non-test code. Use proper error handling instead.
Expand Down
25 changes: 25 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,31 @@ report.summarize().pipe(Some)
entry.file_name().pipe(OsStringDisplay::from).pipe(Some)
```

### Using `command-extra`

The integration tests build `std::process::Command` values with the [`command-extra`](https://docs.rs/command-extra) crate, which offers a chainable, owned style. Import it as `use command_extra::CommandExtra;`. Production code does not spawn subprocesses, so this convention applies only to the tests.

The standard `Command` builder methods, such as `arg`, `env`, and `current_dir`, take `&mut self` and return `&mut Command`. This makes them unsuitable for method chains that end in an owned value. The `CommandExtra` extension trait provides owned counterparts that take ownership and return an owned `Command`, enabling fluent one-expression construction:

```rust
// Good: fully chainable, owned style
let output = Command::new(PDU)
.with_current_dir(&workspace)
.with_arg("--json-output")
.with_stdin(Stdio::null())
.with_stdout(Stdio::piped())
.output()
.expect("spawn pdu");

// Bad: the borrowing builders force a separate mutable binding
let mut command = Command::new(PDU);
command.current_dir(&workspace);
command.arg("--json-output");
let output = command.output().expect("spawn pdu");
```

The trait provides an owned counterpart for each standard builder method, and the names follow three prefix patterns. Methods that add or set a value keep the `with_*` prefix: `with_arg`, `with_args`, `with_current_dir`, `with_env`, `with_stdin`, `with_stdout`, and `with_stderr`. Removal takes the `without_*` prefix, so `without_env` is the counterpart of `env_remove`. Clearing takes the `with_no_*` prefix, so `with_no_env` is the counterpart of `env_clear`.

### Pattern Matching

When mapping enum variants to values, prefer the concise wrapping style:
Expand Down
1 change: 1 addition & 0 deletions template/ai-instructions/shared.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- Use descriptive names for generics, such as `Size` and `Report`. Do not use single letters.
- 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.
- 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)`.
- In test code, use the `command-extra` crate (the `CommandExtra` trait) when building `std::process::Command`. Call `.with_arg(...)`, `.with_env(...)`, `.without_env(...)`, `.with_no_env()`, and similar methods rather than `.arg(...)`, `.env(...)`, `.env_remove(...)`, and `.env_clear()`, so construction remains a single owned expression chain.
- Prefer `where` clauses when a type has multiple trait bounds.
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.
- Minimize `unwrap()` in non-test code. Use proper error handling instead.
Expand Down