Cursor rule
.cursor/rules/rust-coding-style.mdcRust Coding Style
Cursor rules
Quality
69/100
Scores the file, not the repository.Length
1,228 words
15 headings · 5 code blocksRepository
1.6k
— · pushed 0 days agoLast changed
3 days ago
First indexed 3 days ago.123456# Rust Coding Style78## Project-Specific Patterns910- Use the 2024 edition of Rust11- Prefer `derive_more` over manual trait implementations12- Feature flags in this codebase use the `#[cfg(feature = "...")]` pattern13- Invoke `cargo clippy` with `--all-features`, `--all-targets`, and `--no-deps` from the root14- Use `cargo doc --no-deps --all-features` for checking documentation15- Use `rustfmt` to format the code16- Use `#[expect(lint, reason = "...")]` over `#[allow(lint)]`1718## Type System1920- Create strong types with newtype patterns for domain entities21- Implement `hash_graph_types` traits for custom domain types22- Consider visibility carefully (avoid unnecessary `pub`)2324```rust25#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, derive_more::Display)]26pub struct UserId(Uuid);27```2829## Async Patterns3031- Use `impl Future<Output = T> + Send` in trait definitions:3233```rust34fn get_data(35 &self,36 id: String,37) -> impl Future<Output = Result<Data, Report<DataError>>> + Send {38 async move {39 // Implementation40 }41}42```4344## Function Arguments4546- Functions should **never** take more than 7 arguments. If a function requires more than 7 arguments, encapsulate related parameters in a struct.47- Functions that use data immutably should take a reference to the data, while functions that modify data should take a mutable reference. Never take ownership of data unless the function explicitly consumes it.48- Make functions `const` whenever possible.49- Prefer the following argument types when applicable, but only if this does not reduce performance:50 - `impl AsRef<str>` instead of `&str` or `&String`51 - `impl AsRef<Path>` instead of `&Path` or `&PathBuf`52 - `impl IntoIterator<Item = &T>` when only iterating over the data53 - `&[T]` instead of `&Vec<T>`54 - `&mut [T]` instead of `&mut Vec<T>` when the function doesn't need to resize the vector55 - `impl Into<Cow<T>>` instead of `Cow<T>`56 - `impl Into<Arc<T>>` instead of `Arc<T>`57 - `impl Into<Rc<T>>` instead of `Rc<T>`58 - `impl Into<Box<T>>` instead of `Box<T>`59- Never use `impl Into<Option<_>>` as from reading the caller site, it's not visible that `None` could potentially be passed6061## `From` and `Into`6263- Generally prefer `From` implementations over `Into` implementations. The Rust compiler will automatically derive `Into` from `From`, but not vice versa.64- When converting between types, prefer using the `from` method over `into` for clarity. The `from` method makes the target type explicit in the code, while `into` requires type inference.65- For wrapper types like `Cow`, `Arc`, `Rc`, `Report`, and `Box`, prefer using explicit constructors (e.g., `Cow::from`, `Arc::new`) instead of `.into()`. This improves readability by clearly indicating the target type.6667## Smart Pointers6869- When cloning smart pointers such as `Arc` and `Rc`, **always** use `Arc::clone(&pointer)` and `Rc::clone(&pointer)` instead of `pointer.clone()`. This explicitly indicates you're cloning the reference, not the underlying data.7071## Instrumentation7273- Annotate functions that perform significant work with `#[tracing::instrument]`74- Use `tracing` macros (e.g., `trace!`, `debug!`, `info!`, `warn!`, `error!`) instead of `println!` or `eprintln!` for logging7576## Allocations7778- Minimize allocations when possible. For example, reuse a `Vec` in a loop instead of creating a new one in each iteration.79- Prefer borrowed data over owned data where appropriate.80- Balance performance and readability—if an allocation makes code significantly more readable or maintainable, the trade-off may be worthwhile.8182## Types8384- Use newtypes when a value should carry specific semantics beyond its underlying type. This improves type safety and code clarity.8586For example:8788```rust89struct UserId(u64); // instead of `type UserId = u64;` or `u64`90```9192## Naming Conventions9394When suggesting names for variables, functions, or types:9596- Do not prefix test-function names with `test_`, this would otherwise result in `test::test_<name>` names.97- Provide a concise list of naming options with brief explanations of why each fits the context98- Choose names of appropriate length—avoid names that are too long or too short99- Avoid abbreviations unless they are widely recognized in the domain (e.g., `Http` or `Json` is acceptable, but `Ctx` instead of `Context` is not)100- Do not suffix names with their types (e.g., use `users` instead of `usersList`)101- Do not repeat the type name in variable names (e.g., use `user` instead of `userUser`)102103## Crate Preferences104105- Use `similar_asserts` for test assertions106- Use `insta` for snapshot tests107- Use `test_log` for better test output (`#[test_log::test]`)108- Use `tracing` macros, not `log` macros109- Prefer `tracing::instrument` for function instrumentation110111## Import Style112113- Don't use local imports within functions, or blocks114- Avoid wildcard imports like `use super::*;`, or `use crate::module::*;`115- Never use a prelude `use crate::prelude::*`116- Prefer explicit imports to make dependencies clear and improve code readability117- We prefer `core` over `alloc` over `std` for imports to minimize dependencies118 - Use `core` for functionality that doesn't require allocation119 - Use `alloc` when you need allocation but not OS-specific features120 - Only use `std` when necessary for OS interactions or when using `core`/`alloc` would be unnecessarily complex121- Prefer qualified imports (`use foo::Bar; let x = Bar::new()`) over fully qualified paths (`let x = foo::Bar::new()`) for frequently used types122- Use `pub use` re-exports in module roots to create a clean public API123- Avoid importing items with the same name from different modules; use qualified imports124- Import traits using `use module::Trait as _;` when you only need the trait's methods and not the trait name itself125 - This pattern brings trait methods into scope without name conflicts126 - Use this especially for extension traits or when implementing foreign traits on local types127128```rust129// Good - Importing a trait just for its methods:130use std::io::Read as _;131132// Example with trait methods:133fn read_file(file: &mut File) -> Result<String, std::io::Error> {134 // Read methods available without importing the Read trait name135 let mut content = String::new();136 file.read_to_string(&mut content)?;137 Ok(content)138}139140// Bad - Directly importing trait when only methods are needed:141use std::io::Read;142143// Good - Importing trait for implementing it:144use std::io::Write;145impl Write for MyWriter { /* implementation */ }146147// Bad - Wildcard import:148mod tests {149 use super::*; // Wildcard import150151 #[test]152 fn test_something() {153 // Test implementation154 }155}156157// Good - Explicit imports:158mod tests {159 use crate::MyStruct;160 use crate::my_function;161162 #[test]163 fn test_something() {164 // Test implementation165 }166}167168// Bad - Local import:169fn process_data() {170 use std::collections::HashMap; // Local import171 let map = HashMap::new();172 // Implementation173}174175// Good - Module-level import:176use std::collections::HashMap;177178fn process_data() {179 let map = HashMap::new();180 // Implementation181}182183// Bad - Using std when core would suffice:184use std::fmt::Display;185186// Good - Using core for non-allocating functionality:187use core::fmt::Display;188189// Bad - Using std when alloc would suffice:190use std::collections::BTreeSet;191192// Good - Using alloc for allocation without full std dependency:193use alloc::vec::Vec;194195// Appropriate - Using std when needed:196use std::fs::File; // OS-specific functionality requires std197```198199## Libraries and Components200201- Abstract integrations with third-party systems behind traits to maintain clean separation of concerns202203## Comments and Assertions204205- Do not add comments after a line of code; place comments on separate lines above the code they describe206- When using assertions, include descriptive messages using the optional description parameter rather than adding a comment207- All `expect()` messages should follow the format "should ..." to clearly indicate the expected behavior208209For example:210211```rust212// Bad:213assert_eq!(result, expected); // This should match the expected value214215// Good:216assert_eq!(result, expected, "Values should match expected output");217218// Bad:219some_value.expect("The value is not None"); // This should never happen220221// Good:222some_value.expect("should contain a valid value");223```224
Also in hashintel/hash
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 |
|---|---|---|---|---|---|
| hashintel/hash.cursor/rules/ai-assistant-guidelines.mdc · 1.6k | Cursor rules | do-not | 51/100 | 3 days ago | |
| hashintel/hash.cursor/rules/rust-documentation.mdc · 1.6k | Cursor rules | docs | 33/100 | 3 days ago | |
| hashintel/hash.cursor/rules/git-commit-conventions.mdc · 1.6k | Cursor rules | lint-formatstylegitdo-not | 51/100 | 3 days ago | |
| hashintel/hash.cursor/rules/meaningful-identifiers.mdc · 1.6k | Cursor rules | do-not | 32/100 | 3 days ago | |
| hashintel/hash.cursor/rules/rust-error-handling.mdc · 1.6k | Cursor rules | no sections | 31/100 | 3 days ago | |
| hashintel/hash.cursor/rules/rust-testing-strategy.mdc · 1.6k | Cursor rules | testlint-formatstyletesting-strategy | 81/100 | 3 days ago | |
| hashintel/hash.cursor/rules/rust-tracing-practices.mdc · 1.6k | Cursor rules | no sections | 45/100 | 3 days ago | |
| hashintel/hash.cursor/rules/typescript-coding-guidelines.mdc · 1.6k | Cursor rules | styletypesdo-not | 65/100 | 3 days ago | |
| hashintel/hash.cursor/rules/update-rules.mdc · 1.6k | Cursor rules | no sections | 4/100 | 3 days ago | |
| hashintel/hash.github/instructions/code-review.instructions.md · 1.6k | Copilot instructions | lint-formatstylegitdo-not+1 | 78/100 | 3 days ago | |
| hashintel/hash.github/instructions/rust-review.instructions.md · 1.6k | Copilot instructions | lint-formatstylegitdo-not | 73/100 | 3 days ago | |
| hashintel/hash.github/instructions/typescript-review.instructions.md · 1.6k | Copilot instructions | testlint-formatstyletypes+2 | 66/100 | 3 days ago | |
| hashintel/hashAGENTS.md · 1.6k | AGENTS.md | testlint-formatarchtypes+4 | 93/100 | 3 days ago | |
| hashintel/hashlibs/@hashintel/ds-components/AGENTS.md · 1.6k | AGENTS.md | buildtestlint-formatstyle+5 | 97/100 | 3 days ago | |
| hashintel/hashlibs/@hashintel/ds-helpers/AGENTS.md · 1.6k | AGENTS.md | archdependenciesagent-behaviour | 62/100 | 3 days ago | |
| hashintel/hashlibs/@hashintel/petrinaut/AGENTS.md · 1.6k | AGENTS.md | buildtestlint-formatstyle | 80/100 | 3 days ago |
Diff against .cursor/rules/ai-assistant-guidelines.mdc Diff against .cursor/rules/rust-documentation.mdc Diff against .cursor/rules/git-commit-conventions.mdc Diff against .cursor/rules/meaningful-identifiers.mdc Diff against .cursor/rules/rust-error-handling.mdc Diff against .cursor/rules/rust-testing-strategy.mdc Diff against .cursor/rules/rust-tracing-practices.mdc Diff against .cursor/rules/typescript-coding-guidelines.mdc Diff against .cursor/rules/update-rules.mdc Diff against .github/instructions/code-review.instructions.md Diff against .github/instructions/rust-review.instructions.md Diff against .github/instructions/typescript-review.instructions.md Diff against AGENTS.md Diff against libs/@hashintel/ds-components/AGENTS.md Diff against libs/@hashintel/ds-helpers/AGENTS.md Diff against libs/@hashintel/petrinaut/AGENTS.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 3 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 3 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 3 days ago |
