Skip to content
cccskills
FreePublished on GitHub

rust

Idiomatic programming style, patterns, and conventions for Rust development. Trigger when: - Writing, refactoring, reviewing, or debugging Rust code. - Files matching the pattern **/*.rs (including Cargo.toml, Cargo.lock) are in the workspace or referenced. - Tasks involve: cargo build, cargo clippy, cargo test, cargo check, rustc. - Prompt contains keywords: rust, cargo, clippy, borrow checker, lifetime, struct, enum, impl, Option, Result, match, unwrap, unsafe.

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md8.2 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Rust Language Idioms

Work with the language, not against it. Embrace ownership, the borrow checker, and the type system.


Core Values

  • Safety: Lean on the compiler's guarantees. Avoid unsafe unless absolutely necessary.
  • Memory Efficiency: Zero-cost abstractions. Avoid unnecessary allocations.
  • Ergonomics: APIs should be intuitive and hard to misuse.

API Design

Naming Conventions

PrefixSemanticsCostExample
as_Borrowed view, no allocationCheapas_ref(), as_slice()
to_Creates new owned valueExpensiveto_string(), to_vec()
into_Consumes self, transformsCheapinto_iter(), into_inner()

Argument Flexibility

Accept generic bounds instead of concrete types:

// ❌ Inflexible
fn read_file(path: &PathBuf) -> Result<String>

// ✅ Accepts &str, String, PathBuf, &Path
fn read_file(path: impl AsRef<Path>) -> Result<String>

Common patterns:

  • impl AsRef<Path> — for paths
  • impl AsRef<str> — for string-like types
  • impl Into<String> — when ownership is needed

Constructors

  • Simple: T::new() for basic instantiation
  • Configured: T::with_capacity(n) for single-option variants
  • Complex: Use the Builder pattern for 3+ optional fields
let config = ConfigBuilder::new()
    .port(8080)
    .timeout(Duration::from_secs(30))
    .build()?;

Monomorphization Control

For widely-used generic functions, consider splitting:

// Public generic wrapper (thin)
pub fn process(path: impl AsRef<Path>) -> Result<()> {
    process_inner(path.as_ref())
}

// Private concrete implementation (bulk of logic)
fn process_inner(path: &Path) -> Result<()> {
    // ...
}

This reduces binary bloat and compile times.


Error Handling

The ? Operator

Use ? to propagate errors. It:

  1. Unwraps Ok(value) or returns Err(e) early
  2. Automatically converts via From trait

Library vs. Application Errors

ContextApproachCrate
LibrariesCustom enum error typesthiserror
ApplicationsBoxed errors with contextanyhow
// Library: structured, matchable errors
#[derive(Debug, thiserror::Error)]
pub enum ParseError {
    #[error("invalid header at byte {0}")]
    InvalidHeader(usize),
    #[error("unexpected EOF")]
    UnexpectedEof,
}

// Application: rich context chains
fn main() -> anyhow::Result<()> {
    let config = load_config()
        .context("failed to load configuration")?;
    Ok(())
}

Parse, Don't Validate

Encode invariants in the type system:

// ❌ Stringly-typed, requires repeated validation
fn send_email(to: &str) -> Result<()>

// ✅ Invalid states are unrepresentable
fn send_email(to: EmailAddress) -> Result<()>

The constructor for EmailAddress validates once; all downstream code operates with a compile-time guarantee.


Iterators

Iterators are lazy and zero-cost. Build declarative pipelines:

let result: Vec<_> = items
    .iter()
    .filter(|x| x.is_valid())
    .map(|x| x.transform())
    .collect();

Key Adapters

AdapterPurpose
mapTransform each element
filterKeep elements matching predicate
filter_mapFilter and transform in one step
flat_mapMap then flatten nested iterators
zipCombine two iterators into pairs
chainConcatenate iterators
take / skipLimit or offset elements
inspectDebug: observe without modifying

Pitfalls

  • Iterators are lazy—no work until consumed (collect, sum, for_each)
  • Avoid side effects in map; use for_each or explicit loops
  • Use inspect() to debug intermediate pipeline stages

Concurrency

Thread Safety Markers

TraitMeaning
SendOwnership can transfer between threads
SyncReferences (&T) can be shared between threads

Most types are automatically Send + Sync. Types containing raw pointers or interior mutability may not be.

Common Primitives

  • Mutex<T> — mutual exclusion
  • RwLock<T> — multiple readers OR single writer
  • Arc<T> — atomic reference counting for shared ownership
  • mpsc::channel — message passing

Anti-Pattern: if let Deadlock (pre-2024 edition)

// ❌ Lock held through else block in older editions
if let Some(x) = mutex.lock().unwrap().get("key") {
    // ...
} else {
    mutex.lock().unwrap().insert("key", value); // DEADLOCK
}

// ✅ Extract lock explicitly
let guard = mutex.lock().unwrap();
let result = guard.get("key").cloned();
drop(guard); // Release before else

Fixed in Rust 2024 edition.


Type System

Newtypes

Wrap primitives to create distinct types:

struct UserId(u64);
struct PostId(u64);

// Now UserId and PostId are incompatible at compile time

#[must_use]

Apply to functions/types where ignoring the result is almost always a bug:

#[must_use = "this returns a new value and does not modify self"]
fn sorted(&self) -> Vec<T>

impl Trait in Return Position

Hide concrete types when they're implementation details:

fn make_iter() -> impl Iterator<Item = u32> {
    (0..10).filter(|x| x % 2 == 0)
}

Anti-Patterns

Anti-PatternDescriptionRemedy
OverengineeringComplex abstractions, premature unsafe, macro abusePrefer simple, direct solutions
Simplistic DesignFailing to leverage type system (stringly-typed, bool-blind)Use enums/newtypes to encode invariants
Premature OptimizationOptimizing without profilingWrite clear code first; measure, then optimize
Documentation NeglectMissing or stale docsDoc-comments (///) with examples; run cargo doc

Blessed Crates

DomainCrateNotes
Serializationserde + serde_jsonDe facto standard
Async RuntimetokioMost widely supported
CLI ParsingclapFeature-rich, fast
Error (Library)thiserrorDerive for custom errors
Error (Application)anyhowContext chains, backtraces
HTTP ClientreqwestBuilt on tokio
LoggingtracingStructured, async-aware

Quick Reference

  • No .unwrap() in library code — propagate Result
  • No .clone() without justification — prefer references
  • No panic! in library code — return errors
  • Use clippy — cargo clippy -- -D warnings
  • Format with rustfmt — cargo fmt
  • Document public APIs — /// with examples

These idioms refine but are subordinate to the Code-Edit Constraints.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

SOP for auditing AI-generated code. Trigger when: - Reviewing, refactoring, or cleaning up AI-generated code to prevent regressions or hallucinated APIs. - Prompt contains: /ai-audit, code audit, AI cleanup, common flaws.

The English summary is being prepared. Showing the original description.

nrdxp/predicate10Updated Sep 1, 2026

Protocol for auditing API surface coherence and type safety. Trigger when: - Evaluating API designs, interface type safety, or design elegance. - Prompt contains: /api-audit, API surface, API coherence, type safety.

The English summary is being prepared. Showing the original description.

nrdxp/predicate10Updated Sep 1, 2026

Normative sufficiency conditions for Initial Boundary Conditions (IBCs) and the SOP for the cheap-tier boundary refinement loop (/boundary). Trigger when: - Crafting, auditing, or refining a prompt/IBC destined for an expensive (architect-class) model or an autonomous worker dispatch. - Evaluating whether a task frame is sufficient to bound an agent walk. - Prompt contains: /boundary, IBC, initial boundary condition, boundary contract, sufficiency conditions, worker prompt, prompt refinement.

The English summary is being prepared. Showing the original description.

nrdxp/predicate10Updated Sep 1, 2026

SOP for the architect-tier campaign workflow (/campaign): exhaustive survey, mitigation planning, tiered orchestration, and reconciliation. Trigger when: - Running a multi-workstream initiative where an expensive architect-tier council surveys, plans, emits worker prompts, and judges landed work. - Conducting production-readiness assessments that fan out into autonomous mitigation dispatches across model tiers. - Prompt contains: /campaign, campaign workflow, survey, orchestrate, reconcile, premise freshness, tier routing, worker IBC, scratch.

The English summary is being prepared. Showing the original description.

nrdxp/predicate10Updated Sep 1, 2026

Maintain and update the persistent project chronicle (docs/chronicle.md). Trigger when: - The human requests a history summary or chronicle update. - Starting work on a new codebase and needing context on its evolution. - Prompt contains keywords: /chronicle, chronicle, project history, git log summary, history summary.

The English summary is being prepared. Showing the original description.

nrdxp/predicate10Updated Sep 1, 2026

Rules, conventions, and constraints for formatting git commit messages and committing at logical boundaries. Trigger when: - Drafting, revising, or validating git commit messages. - Pausing at commit boundaries under the CORE or CONTINUE workflows. - Evaluating whether a changeset should be split into multiple commits. - Prompt contains keywords: commit message, git commit, conventional commits, commit hygiene, commit guidelines, logical boundary, spaghetti diff, atomic commit, commit boundary.

The English summary is being prepared. Showing the original description.

nrdxp/predicate10Updated Sep 1, 2026

See all skills by nrdxp

Report a problem with this skill