rust-best-practiceslisted
Install: claude install-skill ryo-ebata/cc-audit
# Rust Best Practices for cc-audit
## Error Handling
### Prefer `?` Over `unwrap()`
```rust
// BAD: Panics on error
let content = fs::read_to_string(path).unwrap();
// GOOD: Propagates error
let content = fs::read_to_string(path)?;
// GOOD: With context
let content = fs::read_to_string(path)
.map_err(|e| ScanError::IoError { path: path.into(), source: e })?;
```
### Use `thiserror` for Custom Errors
```rust
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ScanError {
#[error("failed to read file: {path}")]
IoError {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("invalid pattern: {0}")]
InvalidPattern(String),
}
```
### When `unwrap()` is Acceptable
- In tests
- After validation guarantees success
- With `unreachable!()` comment explaining why
```rust
// OK: We just checked is_some()
if value.is_some() {
let v = value.unwrap(); // Known safe
}
// BETTER: Use if-let or match
if let Some(v) = value {
// use v
}
```
## Option and Result Patterns
### Prefer Combinators
```rust
// BAD: Verbose match
let result = match opt {
Some(v) => Some(v.to_uppercase()),
None => None,
};
// GOOD: Use map
let result = opt.map(|v| v.to_uppercase());
// GOOD: Chain combinators
let result = opt
.filter(|s| !s.is_empty())
.map(|s| s.trim())
.unwrap_or_default();
```
### `ok_or` vs `ok_or_else`
```rust
// Use ok_or for cheap errors
let value = opt.ok_or(MyError::NotFound)?;
// Use ok_or