.cursorrules (deprecated)
rules/rust-production/.cursorrules.cursorrules
Quality
81/100
Scores the file, not the repository.Length
1,045 words
15 headings · 9 code blocksRepository
16
— · pushed 109 days agoLast changed
2 days ago
First indexed 2 days ago.1# Rust Production — Cursor Rules2# Production Rust: error handling, async, lifetimes, and systems programming patterns34# Project Context5You are writing production Rust code. The project prioritizes safety, performance, and6clear error handling. Follow Rust idioms, leverage the type system for correctness,7and write code that the borrow checker loves. Use the 2021 edition or later.89# Error Handling (Critical)10- Use `thiserror` for library error types, `anyhow` for application-level errors.11- Define domain-specific error enums:12```rust13 use thiserror::Error;1415 #[derive(Error, Debug)]16 pub enum AppError {17 #[error("User not found: {0}")]18 UserNotFound(UserId),19 #[error("Database error: {0}")]20 Database(#[from] sqlx::Error),21 #[error("Validation failed: {field} — {message}")]22 Validation { field: String, message: String },23 }24```25- Use `Result<T, E>` for all fallible operations. Never panic in library code.26- Use the `?` operator for error propagation — don't call `.unwrap()` in production code.27- Use `.expect("reason")` only when you have a provable invariant — document why.28- Convert between error types with `From` implementations or `.map_err()`.29- DON'T: Use `.unwrap()` — it panics. Use `?`, `.unwrap_or()`, `.unwrap_or_default()`, or match.30- DON'T: Use `panic!()` for expected error conditions — return `Result` instead.3132# Ownership and Borrowing33- Prefer borrowing (`&T`) over owning (`T`) in function parameters when you don't need ownership.34- Use `&str` instead of `String` for function parameters (accept both owned and borrowed).35- Use `&[T]` instead of `Vec<T>` for function parameters (accept any contiguous slice).36- Use `Cow<'_, str>` when you might or might not need to own the data.37- Clone deliberately — add a comment when cloning: `// Clone needed because X takes ownership`.38- Prefer `to_owned()` over `to_string()` for `&str -> String` conversion (more explicit).39- Use `Arc<T>` for shared ownership across threads. Use `Rc<T>` only in single-threaded code.4041# Struct and Type Design42- Use the newtype pattern for type safety:43```rust44 pub struct UserId(pub i64);45 pub struct Email(String);46```47- Derive common traits on all data types: `#[derive(Debug, Clone, PartialEq)]`.48- Add `#[derive(Serialize, Deserialize)]` with serde for API types.49- Use builder pattern for structs with many optional fields:50```rust51 pub struct Config {52 host: String,53 port: u16,54 timeout: Duration,55 }56 impl Config {57 pub fn builder() -> ConfigBuilder { ConfigBuilder::default() }58 }59```60- Use `#[non_exhaustive]` on public enums and structs for future compatibility.6162# Trait Patterns63- Define traits for abstractions that have multiple implementations (repository, client).64- Use `impl Trait` in function return position for zero-cost abstraction:65```rust66 fn create_handler() -> impl Fn(Request) -> Response { ... }67```68- Use `dyn Trait` when you need runtime polymorphism (trait objects, heterogeneous collections).69- Use `where` clauses for complex trait bounds:70```rust71 fn process<T>(item: T) -> Result<Output, Error>72 where73 T: Serialize + Send + 'static,74 { ... }75```76- Implement `Display` for user-facing output, `Debug` for developer logging.7778# Async Patterns (Tokio)79- Use `tokio` as the async runtime. Configure with `#[tokio::main]`.80- Use `tokio::spawn` for concurrent tasks. Use `tokio::join!` for parallel execution.81- Use `tokio::select!` for racing multiple futures.82- For cancellation safety, prefer `tokio_util::sync::CancellationToken`.83- Avoid holding locks across `.await` points — this causes deadlocks.84- Use `tokio::sync::Mutex` instead of `std::sync::Mutex` in async code.85- Prefer channels (`mpsc`, `oneshot`, `broadcast`) for inter-task communication over shared state.86```rust87 let (tx, mut rx) = tokio::sync::mpsc::channel::<Event>(100);88 tokio::spawn(async move {89 while let Some(event) = rx.recv().await {90 process_event(event).await;91 }92 });93```9495# Concurrency96- Use `rayon` for CPU-bound parallelism (data parallelism on iterators).97- Use `tokio` for I/O-bound concurrency (network, file system).98- Prefer message passing over shared state. If sharing state, use `Arc<Mutex<T>>`.99- Use `RwLock` when reads vastly outnumber writes.100- DON'T: Block the async runtime with CPU-intensive work — use `tokio::task::spawn_blocking`.101102# Iterator Patterns103- Chain iterator methods for data transformations:104```rust105 let active_emails: Vec<String> = users.iter()106 .filter(|u| u.is_active)107 .map(|u| u.email.clone())108 .collect();109```110- Use `collect()` with type annotations when the target collection type isn't obvious.111- Use `Iterator::try_fold` and `try_for_each` for fallible iterations.112- Prefer iterators over indexed loops — they're often faster (bounds check elimination).113114# API Design115- Make invalid states unrepresentable through types:116```rust117 // Instead of a `status: String` field, use an enum118 enum OrderState {119 Pending { created_at: DateTime },120 Shipped { tracking_number: String },121 Delivered { delivered_at: DateTime },122 }123```124- Use the typestate pattern for compile-time workflow enforcement:125```rust126 struct HttpRequest<S: State> { ... }127 struct Building;128 struct Ready;129 impl HttpRequest<Building> { fn header(self, ...) -> Self { ... } }130 impl HttpRequest<Building> { fn build(self) -> HttpRequest<Ready> { ... } }131 impl HttpRequest<Ready> { async fn send(self) -> Response { ... } }132```133- Follow the principle: parse, don't validate. Convert raw input into typed structures at boundaries.134135# Testing136- Unit tests go in the same file: `#[cfg(test)] mod tests { ... }`.137- Integration tests go in `tests/` directory.138- Use `#[test]` for sync tests, `#[tokio::test]` for async tests.139- Use `proptest` or `quickcheck` for property-based testing.140- Use `mockall` for trait mocking in unit tests.141- Test error paths as thoroughly as success paths.142- Use `assert_eq!` with descriptive messages: `assert_eq!(result, expected, "user lookup failed")`.143144# Cargo.toml Best Practices145- Pin major versions: `serde = "1"`, not `serde = "1.0.160"` (Cargo resolves to latest compatible).146- Use `[workspace]` for multi-crate projects.147- Enable only needed features: `tokio = { version = "1", features = ["rt-multi-thread", "macros"] }`.148- Use `cargo clippy -- -D warnings` in CI — treat clippy warnings as errors.149- Use `cargo deny` to audit dependencies for security and licensing.150151# Logging and Observability152- Use `tracing` crate (not `log`) for structured, async-aware logging.153- Add `#[instrument]` to key functions for automatic span creation.154- Include context in log messages: user_id, request_id, operation.155- Use span levels appropriately: ERROR, WARN, INFO, DEBUG, TRACE.156157# Common Mistakes to Avoid158- DON'T: Use `.unwrap()` or `.expect()` in production paths — handle errors with `?`.159- DON'T: Clone to satisfy the borrow checker — rethink ownership structure first.160- DON'T: Use `String` where `&str` suffices in function parameters.161- DON'T: Hold a `MutexGuard` across an await point.162- DON'T: Use `unsafe` without a `// SAFETY:` comment explaining the invariant.163- DON'T: Ignore compiler warnings — fix them or understand why they're safe.164- DON'T: Use `Box<dyn Error>` as an error type — use typed errors.165
Also in survivorforge/cursor-rules
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| survivorforge/cursor-rulesrules/ai-ml-python/.cursorrules · 16 | .cursorrules | teststylearchdeployment+2 | 81/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/api-design-rest/.cursorrules · 16 | .cursorrules | lint-formatstylesecurityapi+3 | 69/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/api-microservices/.cursorrules · 16 | .cursorrules | buildteststylearch+5 | 92/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/aws-serverless/.cursorrules · 16 | .cursorrules | teststylearchtypes+6 | 73/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/chrome-extension/.cursorrules · 16 | .cursorrules | teststylearchtesting-strategy+4 | 81/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/clean-code/.cursorrules · 16 | .cursorrules | styledo-notagent-behaviourdocs | 57/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/database-sql/.cursorrules · 16 | .cursorrules | styletypessecuritydatabase+3 | 65/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/devops-docker/.cursorrules · 16 | .cursorrules | setupbuildteststyle+4 | 93/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/devops-infrastructure/.cursorrules · 16 | .cursorrules | buildteststylesecurity+3 | 93/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/django-rest/.cursorrules · 16 | .cursorrules | buildteststylearch+5 | 84/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/docker-devops/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 85/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/flutter-dart/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 89/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/fullstack-nextjs-prisma/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 96/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/go-gin/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+5 | 84/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/go-production/.cursorrules · 16 | .cursorrules | teststylearchtesting-strategy+3 | 89/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/golang-api/.cursorrules · 16 | .cursorrules | buildteststylearch+6 | 84/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/langchain-ai/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+4 | 84/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/mcp-server/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+7 | 68/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/mern-stack/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 81/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/mobile-react-native/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 89/100 | 2 days ago |
Diff against rules/ai-ml-python/.cursorrules Diff against rules/api-design-rest/.cursorrules Diff against rules/api-microservices/.cursorrules Diff against rules/aws-serverless/.cursorrules Diff against rules/chrome-extension/.cursorrules Diff against rules/clean-code/.cursorrules Diff against rules/database-sql/.cursorrules Diff against rules/devops-docker/.cursorrules Diff against rules/devops-infrastructure/.cursorrules Diff against rules/django-rest/.cursorrules Diff against rules/docker-devops/.cursorrules Diff against rules/flutter-dart/.cursorrules Diff against rules/fullstack-nextjs-prisma/.cursorrules Diff against rules/go-gin/.cursorrules Diff against rules/go-production/.cursorrules Diff against rules/golang-api/.cursorrules Diff against rules/langchain-ai/.cursorrules Diff against rules/mcp-server/.cursorrules Diff against rules/mern-stack/.cursorrules Diff against rules/mobile-react-native/.cursorrules
