rust

Robust Rust patterns for file-backed data, parsing, persistence, FFI boundaries, and system integration. Use when writing Rust that handles file formats, subprocess integration, PID/process management, Serde serialization, or UniFFI boundaries. Covers UTF-8 safety, atomic writes, state machines, and defensive error handling.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "rust" with this command: npx skills add petekp/agent-skills/petekp-agent-skills-rust

Rust Engineering Guide

Patterns for building reliable Rust systems that handle file-backed data, external process integration, and cross-language boundaries.

Core Philosophy

Conservative by Default: Inputs from files, subprocesses, and external systems are untrusted.

  • Prefer false negatives over false positives
  • Same input → same output (deterministic)
  • Never panic on user machines due to bad input

Canonical Model Ownership: When Rust is the source of truth, maintain separate representations:

LayerPurposeCharacteristics
Internal domainBusiness logicExpressive enums, rich types
FFI DTOsCross-language boundaryFlat, stable, String-heavy
File formatPersistenceVersioned, round-trippable
External inputValidation boundaryStrictly validated, never trusted

Safe Rust Only: None of these patterns require unsafe. Use ecosystem crates for safe abstractions.


Reference Guides

Load the relevant reference when working in that domain:

DomainReferenceWhen to Load
Data Modelingreferences/data-modeling.mdSerde patterns, UniFFI, strong types, versioned schemas
File I/Oreferences/file-io.mdAtomic writes, concurrency control, file watching
Process Integrationreferences/process-integration.mdPID verification, subprocess handling, timestamps
Text & Parsingreferences/text-and-parsing.mdUTF-8 safety, path normalization, state machines
Testingreferences/testing.mdRound-trip tests, fuzz testing, Clippy lints

Error Handling

Library vs Application Errors

Libraries (public API): Use thiserror with granular error types per operation:

// File operations have their own error type
#[derive(thiserror::Error, Debug)]
pub enum ReadError {
    #[error("failed to read {path}")]
    Io { path: PathBuf, #[source] source: std::io::Error },

    #[error("parse error at line {line}: {message}")]
    Parse { line: usize, message: String },
}

// Subprocess operations have their own error type
#[derive(thiserror::Error, Debug)]
pub enum SubprocessError {
    #[error("failed to spawn process")]
    Spawn(#[source] std::io::Error),

    #[error("process exited with {code:?}: {stderr}")]
    NonZeroExit { code: Option<i32>, stderr: String },

    #[error("output not valid UTF-8")]
    InvalidUtf8(#[source] std::str::Utf8Error),

    #[error("timed out after {0:?}")]
    Timeout(std::time::Duration),
}

Applications (internal/binary): Use anyhow for context-rich errors:

use anyhow::{Context, Result};

fn load_config(path: &Path) -> Result<Config> {
    let content = std::fs::read_to_string(path)
        .with_context(|| format!("failed to read config from {}", path.display()))?;
    // ...
}

Graceful Degradation

Errors degrade functionality, not crash. But log when being lenient:

match parse_metadata(&line) {
    Ok(meta) => entries.push(meta),
    Err(e) => {
        tracing::warn!("skipping malformed entry at line {}: {}", line_num, e);
        // Continue processing other entries
    }
}

Quick Reference

Do

  • Use std::sync::LazyLock for static regex (Rust 1.80+)
  • Hold locks across entire read-modify-write cycles
  • Add #[serde(deny_unknown_fields)] for strict external input
  • Truncate strings with .chars() or graphemes, not byte slicing
  • Write files atomically with sync_all() before rename
  • Verify PID identity with process start time
  • Use saturating_sub for time arithmetic
  • Run cargo clippy -- -D warnings and cargo fmt before commit

Don't

  • Use #[from] without adding context (loses which file failed)
  • Create monolithic error enums spanning unrelated operations
  • Silently ignore errors without logging
  • Slice strings with &s[..N] (panics on char boundaries)
  • Assume directory iteration order is stable
  • Trust subprocess output without validation
  • Use unsafe (not needed for these patterns)

Bugs This Guide Prevents

BugPatternReference
PID reuse "ghost sessions"Store + verify process start timeprocess-integration.md
Timestamp unit mismatch (sec vs ms)Normalize on readprocess-integration.md
UTF-8 panic on truncationUse .chars().take(n)text-and-parsing.md
Lost updates under concurrencyLock spans full read-modify-writefile-io.md
Corrupt file on power losssync_all() before renamefile-io.md
Silent metadata corruptionAnchor updates to heading linestext-and-parsing.md
Old data breaks new code#[serde(default)] + aliasdata-modeling.md

Change Checklist

When modifying these systems, verify:

Schema / Serde

  • New fields use Option + #[serde(default)]
  • Old field names supported via alias (read) or rename (write)
  • External input uses #[serde(deny_unknown_fields)]

Concurrency

  • Mutex held across entire read-modify-write cycle
  • Shared state uses Mutex<T>, not thread_local!
  • File locking documents platform caveats if used

Robustness

  • No panics on file I/O or parse errors
  • Errors logged before being ignored
  • Subprocesses have timeouts

Quality

  • cargo clippy -- -D warnings passes
  • cargo fmt --check passes
  • No unsafe blocks (unless justified and audited)

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

codebase-study-guide

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

openclaw-customizer

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

deep-research

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

explainer-visuals

No summary provided by upstream source.

Repository SourceNeeds Review