К основному содержанию
правило

rust · sanjeed5 — правило для Cursor: что делает и как установить

Правило задаёт стиль для Rust-кода: структуру модулей, типобезопасные паттерны, обработку ошибок и тесты. Подключается ко всем файлам проекта.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/rust.mdc
Открыть на GitHub

Что делает rust

Правило для Cursor описывает организацию Rust-кода по функциям и возможностям, а не по типам файлов. Оно советует держать связанные структуры и их impl в одном модуле, разбивать крупные структуры на небольшие и применять newtype для разных идентификаторов. Для сложной инициализации используется Builder, а ограничения generic-типа переносятся на нужные impl или функции.

В рекомендациях по производительности базовыми коллекциями служат Vec и HashMap; известную ёмкость предлагают задавать заранее. Ошибки, которые можно обработать, возвращаются через Result, а каждый блок unsafe должен иметь комментарий // SAFETY:. В том же правиле описаны модульные тесты с #[test] и проверяемые примеры в rustdoc. Без пояснения // SAFETY: блок unsafe нарушит это правило.

Какие задачи решает

  • организовать модули Rust по функциям
  • разделить крупную структуру на связанные типы
  • защитить идентификаторы от случайной подмены
  • выбрать коллекции и задать их ёмкость
  • оформить ошибки и тесты Rust-кода

Примеры запросов агенту

  • Проверь структуру этого Rust-модуля и предложи разбиение по функциям.
  • Замени смешанные u64-идентификаторы на newtype и обнови вызовы.
  • Проверь обработку ошибок, блоки unsafe и тесты с #[test].

Как установить rust

Вручную: положить файлы

.cursor/rules/rust.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о rust

Как установить rust в Cursor?

Разместите файл правила по пути .cursor/rules/rust.mdc в проекте.

Что делает правило rust?

Оно задаёт рекомендации для структуры Rust-модулей, newtype и Builder, generic-ограничений, коллекций, Result, unsafe и тестов.

Что требуется для блока unsafe?

Перед каждым блоком unsafe нужен комментарий // SAFETY: с объяснением, почему операция сохраняет инварианты безопасности Rust.

Исходный текст

rust.mdc · CC0-1.0
---
description: Definitive guidelines for writing idiomatic, performant, and maintainable Rust code, focusing on modern best practices for structure, patterns, and error handling.
globs: **/*
---
# Rust Best Practices

This guide outlines our team's definitive best practices for writing Rust code. Adhere to these principles to ensure consistency, performance, and maintainability across all projects.

## 1. Code Organization and Structure

### 1.1 Module Structure: Feature-Driven, Not File-Type-Driven
Organize modules by *feature or functionality*, not by separating types from implementations. Keep related structs, enums, and their `impl` blocks together within the same module.

❌ BAD:
```rust
// types.rs
pub struct User { pub id: u64 }
// impls.rs
impl User {
    pub fn new(id: u64) -> Self { Self { id } }
}
```

✅ GOOD:
```rust
// user.rs (or a user/mod.rs)
pub struct User { pub id: u64 }
impl User {
    pub fn new(id: u64) -> Self { Self { id } }
    pub fn get_id(&self) -> u64 { self.id }
}
```

### 1.2 Small, Cohesive Structs
Design structs to be small and focused. Break down complex data into multiple smaller, composable structs. This improves borrow-checker ergonomics and API flexibility.

❌ BAD:
```rust
pub struct OrderProcessor {
    pub order_id: u64, pub customer_id: u64, pub items: Vec<String>,
    pub total_amount: f64, pub payment_status: String,
    pub shipping_address_street: String, pub shipping_address_city: String,
}
```

✅ GOOD:
```rust
pub struct Order {
    pub id: u64, pub customer_id: u64, pub items: Vec<String>,
    pub total_amount: f64, pub payment_status: String,
}
pub struct Address { pub street: String, pub city: String }
pub struct OrderProcessor {
    pub order: Order,
    pub shipping_address: Address,
}
```

## 2. Common Patterns and Anti-patterns

### 2.1 Newtype Pattern for Type Safety
Wrap primitive types in newtype structs to enforce strong typing and prevent logical errors from mixing incompatible IDs or values.

❌ BAD:
```rust
fn process_transaction(user_id: u64, account_id: u64) { /* ... */ }
// Calling with swapped arguments compiles: process_transaction(account.id, user.id);
```

✅ GOOD:
```rust
#[derive(Debug, PartialEq, Eq, Copy, Clone)] pub struct UserId(u64);
#[derive(Debug, PartialEq, Eq, Copy, Clone)] pub struct AccountId(u64);

fn process_transaction(user_id: UserId, account_id: AccountId) { /* ... */ }
// Compiler prevents: process_transaction(account.id, user.id);
```

### 2.2 Builder Pattern for Complex Construction
Use the Builder pattern for structs with many optional fields or complex initialization logic. Avoid it for simple structs with one or two clear constructors.

❌ BAD (for many fields):
```rust
pub struct Config { pub timeout: u64, pub retries: u8 }
impl Config {
    pub fn new(timeout: Option<u64>, retries: Option<u8>) -> Self { /* ... */ }
}
```

✅ GOOD:
```rust
pub struct Config { pub timeout: u64, pub retries: u8 }
impl Config { pub fn builder() -> ConfigBuilder { ConfigBuilder::default() } }

#[derive(Default)] pub struct ConfigBuilder { pub timeout: Option<u64>, pub retries: Option<u8> }
impl ConfigBuilder {
    pub fn timeout(mut self, timeout: u64) -> Self { self.timeout = Some(timeout); self }
    pub fn retries(mut self, retries: u8) -> Self { self.retries = Some(retries); self }
    pub fn build(self) -> Result<Config, &'static str> {
        Ok(Config { timeout: self.timeout.unwrap_or(1000), retries: self.retries.unwrap_or(3) })
    }
}
```

### 2.3 Minimal Generic Bounds on Types
Apply generic bounds only when they are *intrinsic* to the type definition. Place stricter, *derivable* bounds on `impl` blocks or specific functions, not on the struct/enum itself.

❌ BAD:
```rust
pub struct Cache<K: std::hash::Hash + Eq + std::fmt::Debug, V: Clone> { /* ... */ }
```

✅ GOOD:
```rust
pub struct Cache<K, V> { /* ... */ } // K and V are just types

impl<K: std::hash::Hash + Eq, V> Cache<K, V> {
    pub fn new() -> Self { /* ... */ }
}
impl<K: std::fmt::Debug, V: std::fmt::Debug> Cache<K, V> {
    pub fn print_keys(&self) { /* ... */ }
}
```

## 3. Performance Considerations

### 3.1 Default to `Vec` and `HashMap`
Start with `Vec` for sequences and `HashMap` for maps. They are highly optimized and cover most use cases. Only switch to other collections (`VecDeque`, `BTreeMap`, `LinkedList`, etc.) when profiling shows a specific performance bottleneck or a unique functional requirement (e.g., sorted keys for `BTreeMap`).

❌ BAD:
```rust
use std::collections::LinkedList; // Unnecessary for most simple lists
fn process_items(items: LinkedList<String>) { /* ... */ }
```

✅ GOOD:
```rust
use std::collections::HashMap; // Default for key-value pairs
fn process_items(items: Vec<String>) { /* ... */ }
fn lookup_data(data: HashMap<String, u32>) { /* ... */ }
```

### 3.2 Pre-allocate Collection Capacity
When the approximate size of a collection is known beforehand, pre-allocate its capacity to avoid frequent reallocations, which can be costly.

❌ BAD:
```rust
let mut vec = Vec::new();
for i in 0..1000 { vec.push(i); } // Potentially many reallocations
```

✅ GOOD:
```rust
let mut vec = Vec::with_capacity(1000);
for i in 0..1000 { vec.push(i); } // Single allocation
```

## 4. Common Pitfalls and Gotchas

### 4.1 Error Handling: `Result` for Recoverable Errors
Always use `Result<T, E>` for errors that can be handled or propagated. Reserve `panic!` for unrecoverable bugs or situations indicating a programming error.

❌ BAD:
```rust
fn load_config(path: &str) -> String {
    std::fs::read_to_string(path).expect("Failed to read config")
}
```

✅ GOOD:
```rust
fn load_config(path: &str) -> Result<String, std::io::Error> {
    std::fs::read_to_string(path)
}
```

### 4.2 Document `unsafe` Blocks
Every `unsafe` block *must* be preceded by a `// SAFETY:` comment explaining *why* the code inside is sound and upholds Rust's safety invariants.

❌ BAD:
```rust
let mut vec = vec![0];
let ptr = vec.as_mut_ptr();
unsafe { *ptr = 42; } // Missing safety justification
```

✅ GOOD:
```rust
let mut vec = vec![0];
let ptr = vec.as_mut_ptr();
// SAFETY: `ptr` is a valid pointer to `vec[0]`, and we are writing a valid
// integer `42` to it. The vector has at least one element.
unsafe { *ptr = 42; }
```

## 5. Testing Approaches

### 5.1 Unit Tests with `#[test]`
Use `#[test]` for isolated unit tests, typically placed in a `tests` module within the same file as the code being tested.

```rust
// src/lib.rs
pub fn add(a: i32, b: i32) -> i32 { a + b }

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(add(1, 2), 3);
    }
}
```

### 5.2 Example Tests with `rustdoc`
Leverage `rustdoc` for documentation examples. These examples are compiled and run as tests, ensuring your documentation stays up-to-date and correct.

```rust
/// Adds two integers together.
///
/// # Examples
///
/// ```
/// assert_eq!(my_crate::add(5, 3), 8);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Похожие правила IDE

Все правила IDE по теме «Языки программирования» →

Сначала — rust от других авторов.

rust официальный github Правило задаёт рекомендации для Rust-кода и применяется к файлам *.rs. Оно пригодится, когда Copilot пишет или проверяет код на Rust. ★ 40 478звёзд репо rust PatrickJS Свод правил по разработке смарт-контрактов на Solana через Anchor и Solana SDK. Помогает писать программы на Rust без плавающих точек и ошибок в проверке счетов. ★ 41 028звёзд репо rust-patterns affaan-m Задаёт правила идиоматичного Rust: управление владением, типизированные ошибки, сопоставление с образцом и трейты. Пригодится при написании, рефакторинге и ревью Rust-кода. CX Codex +1 5 100установок rust-best-practices apollographql Скилл для написания и ревью Rust-кода по хендбуку Apollo GraphQL: заимствование против клонирования, обработка ошибок, тесты. CX Codex +1 21 200установок rust-testing affaan-m Скилл для написания тестов на Rust: юнит-тесты, интеграционные, async, property-based, моки и покрытие. Пригодится, когда ведёшь проект по TDD. CX Codex +1 5 600установок tdd-rust rtk-ai Скилл для разработки RTK-фильтров по методу TDD. Пишешь тест на реальных данных, реализуешь минимум кода, проверяешь экономию токенов — и фиксируешь формат вывода снимком через insta. CX Codex +1 1 400установок migrate-to-rust официальный google Скилл переносит кодовые базы C++, Fortran, Java, Python и C на безопасный Rust с замерами производительности. CX Codex 538установок rust-general PatrickJS Правило задаёт практики для безопасного и идиоматичного Rust-кода. Оно пригодится при работе с .rs, Cargo.toml и Cargo.lock. ★ 41 028звёзд репо

Из того же набора240

Весь набор →
scipy Набор правил для написания научного кода на SciPy в Cursor: оформление docstrings, именованные аргументы и вычисления. ★ 3 580звёзд репо scikit-learn Правило направляет Cursor при работе с Python-кодом scikit-learn: помогает оформлять предобработку и модели через Pipeline и не допускать утечки данных. ★ 3 580звёзд репо scikit-image Правило задаёт команде единый стиль работы с scikit-image: неизменяемость входных массивов, float-диапазон [0, 1], векторизация вместо циклов по пикселям. ★ 3 580звёзд репо sanic Задаёт стандарты асинхронной разработки на Sanic в Python: фабрика create_app, Blueprints, вынос блокирующих вызовов в воркеры и запуск задач в фоне. ★ 3 580звёзд репо ruby Правило для Cursor задаёт команде единый стиль Ruby: RuboCop, соглашения Rails, работа с N+1 и защита от SQL-инъекций. ★ 3 580звёзд репо ros Задаёт стандарты разработки пакетов ROS 2 на C++ и Python в Cursor. Помогает настроить линтеры ament, компоновку нод и многопоточные исполнители. ★ 3 580звёзд репо rocket Правило задаёт рекомендации по структуре и разработке backend-сервисов на Rocket: от маршрутов и валидации до асинхронных обработчиков и ошибок. ★ 3 580звёзд репо riverpod Правило для Cursor задаёт команде единый стиль работы с Riverpod в Flutter: где держать провайдеры, когда ref.watch, а когда ref.read. ★ 3 580звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой