- Embrace ownership and borrowing. Prefer borrowing (`&T`, `&mut T`) over cloning unless necessary.
- Use `Result<T, E>` for fallible operations and `Option<T>` for optional values — propagate errors with `?` operator instead of `unwrap()`.
- Use `impl Trait` in function signatures for return types and `&dyn Trait` for dynamic dispatch — prefer generics over trait objects when possible.
- Use `?` operator for error propagation. Define custom error types with `thiserror` or implement `std::error::Error`.
- Prefer iterators and combinators (`.map()`, `.filter()`, `.collect()`) over manual loops.
- Use `clippy` lints and fix all warnings. Run `cargo fmt` before every commit.
- Use `#[derive(...)]` for common traits: `Debug`, `Clone`, `PartialEq`, `Serialize`, `Deserialize`.
- Prefer `&str` over `String` in function parameters; return `String` when ownership transfer is needed.