
Rust Implement
- 188 installs
- 191 repo stars
- Updated July 24, 2026
- pproenca/dot-skills
rust-implement: A skill for development. This provides functionality for development workflows.
Key points
- rust-implement
Rust Implement by the numbers
- 188 all-time installs (skills.sh)
- +6 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #2,140 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/pproenca/dot-skills --skill rust-implementAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 188 |
|---|---|
| repo stars | ★ 191 |
| Last updated | July 24, 2026 |
| Repository | pproenca/dot-skills ↗ |
How do I use rust-implement for development tasks?
Use rust-implement for development tasks
Who is it for?
Best when you're working on backend & apis and need structured help with rust-implement.
Skip if: Teams with no backend & apis needs, or anyone wanting a generic chat assistant without this specific workflow.
When should I use this skill?
When you need to use rust-implement for development tasks, or when rust-implement: a skill for development. this provides functionality for development workflows.
What you get
Structured output aligned to rust-implement: rust-implement.
Files
Rust Implementation Discipline
Write code in passes. Experts don't produce perfect code in one shot -- they design, implement, review, and simplify. Follow this process for every module you write.
---
Pass 1: Design Types and Signatures
Before writing any implementation, write ONLY the type definitions and function signatures. No bodies. No logic.
Ask yourself these questions before moving on:
- Can any enum state represent an invalid combination? If yes, restructure so invalid states are unrepresentable.
- Are all parameters self-documenting? Replace
boolparams with enums (Transformation 2). - Does every struct that will be serialized or compared use
BTreeMap, notHashMap(Transformation 3)? - Do config structs derive
Default(Transformation 6)? - Would a caller confuse the order of String parameters? Use newtypes.
- Does any struct have 2+
Option<T>fields where only one combination is valid at a time? Convert to an enum (Transformation 8). - Does any function take 4+ parameters? Replace with an args struct (Transformation 9).
Do not proceed to Pass 2 until the types are right. Types are the architecture.
---
Pass 2: Implement
Fill in the function bodies. As you write each function, apply these rules:
- Every
?gets.context("failed to [verb] [noun]")-- no exceptions (Transformation 1). - For library code: use
thiserrorfor error enums. For application code: useanyhow. - Use
Cow<str>when a function sometimes borrows and sometimes allocates (Transformation 7). - Return named structs, not tuples, from any function with 2+ return values (Transformation 5).
- Exhaustive match arms -- no
_ =>wildcards (Transformation 4).
Thread-Through Plumbing
When adding a new field that needs to reach execution sites, trace the full path and explicitly name every intermediate layer before writing code. For each hop, state the module and struct/function that carries the value. If you skip a layer, the field silently disappears at runtime.
Drop/Teardown Precision
- Drop lock guards before any
.await-- a heldMutexGuardacross an await blocks the executor. - Close stdin explicitly in
Dropimpls. Brief wait, then fallback kill. - Use
kill_on_drop(true)for child processes that must not outlive their parent. - Order cleanup deterministically: clear listeners -> drain tasks -> drop resources.
Defensive Serialization
BEGIN IMMEDIATEnotBEGINfor SQLite write transactions (preventsSQLITE_BUSY_SNAPSHOT).- Serialize lock acquisition rather than adding retries.
ON CONFLICT DO NOTHINGover read-then-write for idempotent inserts.
Orphan Event Handling
When events arrive for entities that no longer exist (dead agents, closed threads), handle explicitly. Never silently drop -- log a warning and clean up stale state. Panicking on an orphan event is always wrong.
Ownership Decision Tree
Walk this tree in order when you need shared access to data:
1. Can you pass a reference? Use &T. Zero cost, zero complexity. 2. Might it be owned or borrowed? Use Cow<'_, str>. Zero-cost when borrowed. 3. Multiple owners across sync boundaries? Use Arc<T>. Prefer Arc::clone(&x) over x.clone(). 4. Multiple owners AND mutability? Use Arc<Mutex<T>> or Arc<RwLock<T>>. Choose RwLock when reads vastly outnumber writes. 5. Fire-and-forget spawn? Use move closure with owned data.
Every .clone() is a decision point. Ask: "Is this clone necessary, or can I restructure to borrow?"
Error Philosophy
| Context | Tool | Why |
|---|---|---|
| Application code (main, CLI, tests) | anyhow::Result + .context() | Rich error chains, no boilerplate |
| Library code (crates consumed by others) | thiserror enums | Typed, matchable, callers can branch on variants |
Error enum design: user-facing messages tell the user what to do, not what went wrong internally. Box<T> large payloads. Classify every variant explicitly in is_retryable() -- no wildcards.
Async Decisions
When to `Box::pin`: When thin async wrappers inline large callee futures into their state machine, causing stack pressure. Wrap the inner call: Box::pin(self.inner_method(args)).await.
| Need | Channel | Why |
|---|---|---|
| One response back | oneshot | Exactly one value, then done |
| Stream of events | mpsc | Multiple producers, single consumer |
| Latest value only | watch | Receivers always see the most recent value |
| Broadcast to all | broadcast | Every receiver gets every message |
Shutdown: use CancellationToken for hierarchical shutdown. Never rely on Drop for ordered async cleanup. Never hold a MutexGuard across an .await point.
---
Pass 3: Simplify
Review your code as if you're trying to REMOVE things, not add them.
Three diagnostic questions:
1. Is any parameter just forwarded through a call chain? Remove it, use ambient access. 2. Is any field or function unused? Delete it. 3. Is any abstraction unjustified? (single-use helper, wrapper that adds nothing) Inline it.
"Rewrite, don't rewire" principle: When the bug is in a function's internal logic, rewrite the body with explicit checks. Don't delegate to an existing API that happens to produce the correct result for now -- the explicit version is more auditable and survives upstream changes.
If you added more code than the task strictly requires, something is wrong. Cut it.
---
Pass 4: Verify
Run the bundled lint script on your code:
bash ${SKILL_DIR}/scripts/lint.sh <your-file.rs>Fix every ERROR. Review every WARNING. Then do the manual checklist:
[ ] Every ? has .context("failed to [verb] [noun]")
[ ] No unwrap() outside #[cfg(test)]
[ ] BTreeMap where output is serialized or compared
[ ] No bool parameters -- use enums
[ ] Match arms exhaustive -- no _ => wildcards
[ ] Config structs derive Default
[ ] No single-use helper functions -- inline if called once
[ ] Module under 500 lines (excluding tests)
[ ] No unnecessary .clone() -- prefer borrowing
[ ] Return structs, not tuples, for multi-value returns
[ ] Cow<str> where allocation is conditional
[ ] serde attrs present: rename_all, default, deny_unknown_fields as needed
[ ] No struct with 2+ Option<T> fields that should be an enum
[ ] No function with 4+ parameters (use args struct)
[ ] Lock guards dropped before any .await
[ ] Events for dead/missing entities handled explicitlyFix every violation before presenting the code.
---
Quick Reference: The 9 Transformations
Each transformation shows the exact delta between first-draft and production-grade.
1. .context() on Every ? Operator
BEFORE:
let content = std::fs::read_to_string(path)?;
let config: Config = toml::from_str(&content)?;AFTER:
let content = std::fs::read_to_string(path)
.context("failed to read config file")?;
let config: Config = toml::from_str(&content)
.context("failed to parse TOML config")?;Pattern: "failed to [verb] [noun]". The upstream error describes itself -- your job is to name the operation that broke.
2. Enums Over Booleans
BEFORE:
fn create_sandbox(network: bool, writable: bool) -> Sandbox {AFTER:
fn create_sandbox(network: NetworkMode, access: AccessLevel) -> Sandbox {foo(true, false) is meaningless. Replace with enums so callsites read NetworkMode::Restricted, AccessLevel::ReadOnly. When you cannot change the API, add /*param_name*/ comments before opaque literals.
3. BTreeMap for Serialized or Compared Data
BEFORE: HashMap<String, Rule> -- AFTER: BTreeMap<String, Rule>
HashMap iteration order is random -- diffs become noisy, snapshot tests flake. Use BTreeMap whenever data is serialized, compared in tests, or shown to users.
4. Exhaustive Match Without Wildcards
BEFORE:
match decision {
PolicyDecision::Allow => true,
_ => false,
}AFTER:
match decision {
PolicyDecision::Allow => true,
PolicyDecision::Block { .. } => false,
PolicyDecision::Rewrite { .. } => false,
PolicyDecision::Ask { .. } => false,
}When a new variant is added, the compiler flags every match that needs updating. Wildcards hide this.
5. Return Structs Over Tuples
BEFORE: fn build_command() -> (Vec<String>, Vec<OwnedFd>) -- caller writes result.0 AFTER: fn build_command() -> CommandOutput -- caller writes output.args, output.preserved_fds
Named fields are self-documenting. Define a struct for any function returning 2+ values.
6. Default Derive on Config Structs
#[derive(Default)]
pub struct ServerConfig {
pub timeout_secs: u64,
pub max_retries: u32,
pub bind_addr: String,
}
let config = ServerConfig { timeout_secs: 30, ..Default::default() };Derive Default so callers override only what matters. For non-zero defaults, implement Default manually.
7. Cow<str> for Conditional Ownership
BEFORE:
fn normalize_path(input: &str) -> String {
if needs_normalization(input) { input.replace('\\', "/") }
else { input.to_string() } // allocates even when unchanged
}AFTER:
fn normalize_path(input: &str) -> Cow<'_, str> {
if needs_normalization(input) { Cow::Owned(input.replace('\\', "/")) }
else { Cow::Borrowed(input) } // zero-cost when unchanged
}Cow<str> avoids the unconditional allocation when only some paths need to allocate.
8. Enum-as-Disjoint-Union
BEFORE:
struct Permissions {
profile_name: Option<String>, // only for named profiles
sandbox_policy: Option<SandboxPolicy>, // only for legacy
file_paths: Option<Vec<PathBuf>>, // only when sandbox_policy is set
}AFTER:
enum Permissions {
Named { profile_name: String },
Legacy { sandbox_policy: SandboxPolicy, file_paths: Vec<PathBuf> },
}When a struct has Option<T> fields valid only in certain combinations, it permits invalid states at the type level. Convert to an enum where each variant carries only its relevant data. Diagnostic: if you see 2+ Option<T> fields with is_some()/is_none() guards, it should be an enum.
9. Struct-for-Long-Parameter-Lists
BEFORE:
fn spawn_process(
cmd: &str,
args: &[String],
env: &BTreeMap<String, String>,
cwd: &Path,
stdin_policy: StdinPolicy,
sandbox: SandboxPolicy,
timeout: Duration,
) -> Result<Child> {AFTER:
struct SpawnArgs<'a> {
cmd: &'a str,
args: &'a [String],
env: &'a BTreeMap<String, String>,
cwd: &'a Path,
stdin_policy: StdinPolicy,
sandbox: SandboxPolicy,
timeout: Duration,
}
fn spawn_process(args: &SpawnArgs<'_>) -> Result<Child> {At 4+ parameters, callsites become hard to read and easy to misorder. An args struct names each field at the callsite and makes future parameter additions non-breaking.
Rust Implement
This curated skill mirrors SKILL.md. When maintaining it, keep the workflow focused on type design, implementation, simplification, and verification with Rust tooling.
{
"version": "1.0.6",
"organization": "dot-skills",
"technology": "Rust Implementation",
"date": "March 2026",
"abstract": "Portable Rust implementation skill combining transformation examples, decision frameworks, and a mandatory self-review checklist. Teaches the specific behavioral changes that distinguish expert from competent Rust: .context() discipline, exhaustive matching, BTreeMap for determinism, enum-over-bool type design, and incremental migration patterns.",
"references": [
"https://doc.rust-lang.org/book/",
"https://rust-lang.github.io/api-guidelines/",
"https://docs.rs/anyhow/latest/anyhow/",
"https://docs.rs/thiserror/latest/thiserror/"
]
}
#!/usr/bin/env bash
# lint.sh — checks Rust code for production discipline violations
# Usage: bash lint.sh <file.rs>
set -euo pipefail
FILE="${1:?Usage: lint.sh <file.rs>}"
ERRORS=0
# Find where test module starts (to exclude test code from prod checks)
TEST_LINE=$(grep -n '#\[cfg(test)\]' "$FILE" 2>/dev/null | head -1 | cut -d: -f1)
if [ -z "$TEST_LINE" ]; then
TEST_LINE=$(wc -l < "$FILE")
fi
# 1. unwrap() in production code
UNWRAPS=$(head -n "$TEST_LINE" "$FILE" | grep -n '\.unwrap()' | grep -v '// lint:allow' || true)
if [ -n "$UNWRAPS" ]; then
echo "ERROR: unwrap() in production code:"
echo "$UNWRAPS"
ERRORS=$((ERRORS + 1))
fi
# 2. HashMap where BTreeMap might be appropriate (in struct definitions)
HASHMAPS=$(head -n "$TEST_LINE" "$FILE" | grep -n 'HashMap' | grep -v 'use ' | grep -v '//' || true)
if [ -n "$HASHMAPS" ]; then
echo "WARNING: HashMap found — consider BTreeMap for deterministic output:"
echo "$HASHMAPS"
fi
# 3. Wildcard match arms _ => (excluding slice/tuple/char patterns)
WILDCARDS=$(head -n "$TEST_LINE" "$FILE" | grep -n '_ =>' | grep -v '// lint:allow' || true)
if [ -n "$WILDCARDS" ]; then
echo "WARNING: Wildcard match arm _ => found — prefer exhaustive matching:"
echo "$WILDCARDS"
fi
# 4. bool parameters in public function signatures
BOOL_PARAMS=$(head -n "$TEST_LINE" "$FILE" | grep -n 'pub.*fn.*\bbool\b' | grep -v 'Result<bool' | grep -v -- '-> bool' || true)
if [ -n "$BOOL_PARAMS" ]; then
echo "WARNING: bool parameter in public function — consider using an enum:"
echo "$BOOL_PARAMS"
fi
# 5. Tuple return types in public functions
TUPLE_RETURNS=$(head -n "$TEST_LINE" "$FILE" | grep -n 'pub.*fn.*->.*(' | grep -v -e 'Result' -e 'Option' -e 'impl ' || true)
if [ -n "$TUPLE_RETURNS" ]; then
echo "WARNING: Tuple return type — consider a named struct:"
echo "$TUPLE_RETURNS"
fi
# 6. Missing Display impl for public enums
PUB_ENUMS=$(head -n "$TEST_LINE" "$FILE" | grep -c 'pub enum' || true)
DISPLAY_IMPLS=$(grep -c 'impl.*Display\|#\[derive.*Display' "$FILE" || true)
if [ "$PUB_ENUMS" -gt "$DISPLAY_IMPLS" ] 2>/dev/null; then
echo "INFO: $PUB_ENUMS public enum(s) but only $DISPLAY_IMPLS Display impl(s)"
fi
# 7. Bare ? without .context() — flag lines with ? that lack context/with_context
BARE_Q=$(head -n "$TEST_LINE" "$FILE" | grep -n '?\s*;' | grep -v '\.context\|\.with_context\|// lint:allow' || true)
if [ -n "$BARE_Q" ]; then
echo "ERROR: Bare ? without .context():"
echo "$BARE_Q"
ERRORS=$((ERRORS + 1))
fi
# Summary
if [ "$ERRORS" -gt 0 ]; then
echo ""
echo "FAILED: $ERRORS error(s) found"
exit 1
else
echo ""
echo "PASSED (check warnings above)"
exit 0
fi
Related skills
FAQ
What does rust-implement do?
rust-implement: A skill for development. This provides functionality for development workflows.
When should I use rust-implement?
When you need to use rust-implement for development tasks, or when rust-implement: a skill for development. this provides functionality for development workflows.
What are the main capabilities?
rust-implement.