Rust Implementation Patterns
Use this skill for idiomatic Rust with a practical bias toward Tauri-backed desktop application logic. Assume the Rust side often owns heavy operations such as filesystem work, process orchestration, indexing, background tasks, editor services, and stable IPC with the frontend.
Delivery Workflow
Use the checklist below and track progress:
Rust progress:
- [ ] Step 1: Discover crate boundaries, module layout, and Tauri integration points
- [ ] Step 2: Model ownership, data flow, and error shapes explicitly
- [ ] Step 3: Implement logic with small focused types and functions
- [ ] Step 4: Handle async work, IO, and concurrency without blocking UI flows
- [ ] Step 5: Verify tests, formatting, linting, and boundary behavior
Core Rust Rules
- Model ownership intentionally before writing broad mutable flows.
- Prefer simple types and explicit lifetimes over clever abstractions.
- Use the type system to make invalid states difficult to represent.
- Keep functions small, intention-revealing, and focused on one capability.
- Avoid writing TypeScript, C++, or Java in Rust syntax.
Data Modeling and Errors
- Prefer structs and enums that encode real domain meaning.
- Use
Result and Option intentionally; do not erase failure modes behind generic strings.
- Model recoverable application errors explicitly and keep infrastructure errors distinguishable.
- Use
thiserror or the project-standard error pattern when structured errors improve clarity.
- Keep serialization DTOs separate from internal domain types when the boundary is non-trivial.
Async, IO, and Concurrency
- Keep blocking filesystem, process, or indexing work off the main async path when it can stall responsiveness.
- Use the project's async runtime conventions consistently.
- Preserve cancellation and shutdown behavior where long-running tasks exist.
- Prefer message passing, task isolation, or scoped ownership over broad shared mutable state.
- Make background work observable and controllable when it affects the UI experience.
Tauri Boundaries
- Keep Tauri commands thin: parse input, delegate work, map output, return serializable results.
- Keep frontend-facing DTOs stable and explicit.
- Do not leak internal Rust-only types directly across the Tauri boundary.
- Keep app state injection and shared service ownership clear.
- Move heavy desktop capabilities such as file scanning, process launching, indexing, and project analysis into focused Rust services rather than command handlers.
Command-to-Service Decomposition
When Tauri command count grows, enforce this split:
- Command handler: boundary parsing, auth/guard checks, error mapping, response DTO
- Service: business workflow and orchestration
- Repository/adapter: IO boundaries (filesystem, process, network, toolchain)
Rule of thumb:
- if a command handler exceeds ~40-60 LOC or owns multiple failure branches, extract a service method
- avoid commands calling other commands; share service functions instead
Custom IDE-Oriented Concerns
- Keep editor features separated by capability: workspace, files, diagnostics, search, indexing, processes, language tooling.
- Design long-running services so they can be refreshed, cancelled, or restarted predictably.
- Treat filesystem watchers, subprocesses, and background indexing as failure-prone boundaries.
- Make state transitions explicit for loading, ready, stale, rebuilding, and failed states when those affect the desktop UX.
- Prefer incremental and capability-focused architecture over one giant app state object.
Module and Crate Hygiene
- Keep modules organized around cohesive responsibilities.
- Extract shared logic only when the boundary is real and stable.
- Avoid prematurely splitting crates if module boundaries are sufficient.
- Keep public APIs small and intention-revealing.
Large Module Split Patterns
For large desktop Rust modules:
- split by capability (
commands, service, types, errors, tests) before splitting by technical layer
- keep
mod.rs (or top module) as composition root, not implementation dump
- isolate pure logic into testable leaf modules and keep side-effectful adapters thin
- maintain explicit ownership map for managers to avoid cross-module mutable coupling
Performance and Memory
- Allocate consciously in hot paths, but do not micro-optimize before the design is clear.
- Prefer clear ownership and correct behavior before low-level tuning.
- Avoid unnecessary cloning in critical paths, but do not contort code to eliminate harmless clones.
- Make cache and indexing invalidation rules explicit.
Async Background Worker Patterns
- model worker lifecycle explicitly:
init -> running -> stopping -> stopped
- pair every spawned task with cancellation and join/cleanup path
- avoid detached
spawn without owner; assign each worker to manager/supervisor
- protect long-running loops with backoff + error reporting instead of tight retry loops
- expose runtime health/state for UI-facing workflows (ready, busy, degraded)
Test Matrix (Rust + Tauri Runtime)
Boundary:
- [ ] Tauri command DTO and error mapping tests
- [ ] Command handlers remain thin and delegate correctly
Lifecycle:
- [ ] Manager init/startup path covered
- [ ] Worker cancellation and shutdown path covered
- [ ] Relaunch/restart path does not duplicate workers/listeners
Reliability:
- [ ] Failure path tests for IO/process boundaries
- [ ] Concurrency/race-prone paths validated with deterministic tests where possible
Rust Review Checklist
Correctness:
- [ ] Ownership and mutation boundaries are clear
- [ ] Error handling is explicit and meaningful
- [ ] Async and blocking work are separated appropriately
Architecture:
- [ ] Module boundaries are cohesive
- [ ] Tauri commands stay thin
- [ ] Heavy IDE capabilities live in dedicated services
Quality:
- [ ] Public API is intention-revealing
- [ ] Serialization boundaries are explicit
- [ ] Tests cover critical flows and failure paths
- [ ] `cargo fmt` and `clippy` expectations are respected
Anti-Patterns to Avoid
| Anti-Pattern |
Instead Do |
| One massive Tauri command doing everything |
Delegate to focused Rust services |
| Command handler orchestrates business logic + IO + mapping |
Split into boundary handler + service + adapter |
Generic String errors everywhere |
Use structured errors or explicit variants |
unwrap() in production request or command paths |
Propagate typed errors with ? and map at boundaries |
| Cloning to silence borrow checker issues |
Refactor ownership/borrowing instead of allocating around the problem |
| Shared mutable state spread across tasks |
Isolate ownership and coordinate intentionally |
| Blocking IO inside latency-sensitive async paths |
Offload or separate blocking work clearly |
| Giant global app state for all IDE capabilities |
Split state by capability and ownership |
| Over-abstracting lifetimes and generics too early |
Keep APIs concrete until a real abstraction appears |
| Detached background task with no cancellation path |
Assign owner manager and implement stop/join cleanup |
Connected Skills
technical-context-discovery - follow existing Rust and Tauri conventions before editing
code-review - validate correctness, boundaries, and runtime behavior
1---2name: rust3description: Rust implementation and review patterns for systems, backend, and desktop application logic. Use when Codex needs to build, refactor, debug, or review Rust code involving ownership, borrowing, async workflows, error handling, modules, serialization, concurrency, or performance-sensitive logic, especially when Rust is used with Tauri for advanced desktop applications such as a custom IDE.4metadata:5 source: https://skillmd.com/skills/jakubmikolajek/rust6---78# Rust Implementation Patterns910Use this skill for idiomatic Rust with a practical bias toward Tauri-backed desktop application logic. Assume the Rust side often owns heavy operations such as filesystem work, process orchestration, indexing, background tasks, editor services, and stable IPC with the frontend.1112## Delivery Workflow1314Use the checklist below and track progress:1516```17Rust progress:18- [ ] Step 1: Discover crate boundaries, module layout, and Tauri integration points19- [ ] Step 2: Model ownership, data flow, and error shapes explicitly20- [ ] Step 3: Implement logic with small focused types and functions21- [ ] Step 4: Handle async work, IO, and concurrency without blocking UI flows22- [ ] Step 5: Verify tests, formatting, linting, and boundary behavior23```2425## Core Rust Rules2627- Model ownership intentionally before writing broad mutable flows.28- Prefer simple types and explicit lifetimes over clever abstractions.29- Use the type system to make invalid states difficult to represent.30- Keep functions small, intention-revealing, and focused on one capability.31- Avoid writing TypeScript, C++, or Java in Rust syntax.3233## Data Modeling and Errors3435- Prefer structs and enums that encode real domain meaning.36- Use `Result` and `Option` intentionally; do not erase failure modes behind generic strings.37- Model recoverable application errors explicitly and keep infrastructure errors distinguishable.38- Use `thiserror` or the project-standard error pattern when structured errors improve clarity.39- Keep serialization DTOs separate from internal domain types when the boundary is non-trivial.4041## Async, IO, and Concurrency4243- Keep blocking filesystem, process, or indexing work off the main async path when it can stall responsiveness.44- Use the project's async runtime conventions consistently.45- Preserve cancellation and shutdown behavior where long-running tasks exist.46- Prefer message passing, task isolation, or scoped ownership over broad shared mutable state.47- Make background work observable and controllable when it affects the UI experience.4849## Tauri Boundaries5051- Keep Tauri commands thin: parse input, delegate work, map output, return serializable results.52- Keep frontend-facing DTOs stable and explicit.53- Do not leak internal Rust-only types directly across the Tauri boundary.54- Keep app state injection and shared service ownership clear.55- Move heavy desktop capabilities such as file scanning, process launching, indexing, and project analysis into focused Rust services rather than command handlers.5657### Command-to-Service Decomposition5859When Tauri command count grows, enforce this split:6061- Command handler: boundary parsing, auth/guard checks, error mapping, response DTO62- Service: business workflow and orchestration63- Repository/adapter: IO boundaries (filesystem, process, network, toolchain)6465Rule of thumb:66- if a command handler exceeds ~40-60 LOC or owns multiple failure branches, extract a service method67- avoid commands calling other commands; share service functions instead6869## Custom IDE-Oriented Concerns7071- Keep editor features separated by capability: workspace, files, diagnostics, search, indexing, processes, language tooling.72- Design long-running services so they can be refreshed, cancelled, or restarted predictably.73- Treat filesystem watchers, subprocesses, and background indexing as failure-prone boundaries.74- Make state transitions explicit for loading, ready, stale, rebuilding, and failed states when those affect the desktop UX.75- Prefer incremental and capability-focused architecture over one giant app state object.7677## Module and Crate Hygiene7879- Keep modules organized around cohesive responsibilities.80- Extract shared logic only when the boundary is real and stable.81- Avoid prematurely splitting crates if module boundaries are sufficient.82- Keep public APIs small and intention-revealing.8384### Large Module Split Patterns8586For large desktop Rust modules:8788- split by capability (`commands`, `service`, `types`, `errors`, `tests`) before splitting by technical layer89- keep `mod.rs` (or top module) as composition root, not implementation dump90- isolate pure logic into testable leaf modules and keep side-effectful adapters thin91- maintain explicit ownership map for managers to avoid cross-module mutable coupling9293## Performance and Memory9495- Allocate consciously in hot paths, but do not micro-optimize before the design is clear.96- Prefer clear ownership and correct behavior before low-level tuning.97- Avoid unnecessary cloning in critical paths, but do not contort code to eliminate harmless clones.98- Make cache and indexing invalidation rules explicit.99100## Async Background Worker Patterns101102- model worker lifecycle explicitly: `init -> running -> stopping -> stopped`103- pair every spawned task with cancellation and join/cleanup path104- avoid detached `spawn` without owner; assign each worker to manager/supervisor105- protect long-running loops with backoff + error reporting instead of tight retry loops106- expose runtime health/state for UI-facing workflows (ready, busy, degraded)107108## Test Matrix (Rust + Tauri Runtime)109110```111Boundary:112- [ ] Tauri command DTO and error mapping tests113- [ ] Command handlers remain thin and delegate correctly114115Lifecycle:116- [ ] Manager init/startup path covered117- [ ] Worker cancellation and shutdown path covered118- [ ] Relaunch/restart path does not duplicate workers/listeners119120Reliability:121- [ ] Failure path tests for IO/process boundaries122- [ ] Concurrency/race-prone paths validated with deterministic tests where possible123```124125## Rust Review Checklist126127```128Correctness:129- [ ] Ownership and mutation boundaries are clear130- [ ] Error handling is explicit and meaningful131- [ ] Async and blocking work are separated appropriately132133Architecture:134- [ ] Module boundaries are cohesive135- [ ] Tauri commands stay thin136- [ ] Heavy IDE capabilities live in dedicated services137138Quality:139- [ ] Public API is intention-revealing140- [ ] Serialization boundaries are explicit141- [ ] Tests cover critical flows and failure paths142- [ ] `cargo fmt` and `clippy` expectations are respected143```144145## Anti-Patterns to Avoid146147| Anti-Pattern | Instead Do |148|---|---|149| One massive Tauri command doing everything | Delegate to focused Rust services |150| Command handler orchestrates business logic + IO + mapping | Split into boundary handler + service + adapter |151| Generic `String` errors everywhere | Use structured errors or explicit variants |152| `unwrap()` in production request or command paths | Propagate typed errors with `?` and map at boundaries |153| Cloning to silence borrow checker issues | Refactor ownership/borrowing instead of allocating around the problem |154| Shared mutable state spread across tasks | Isolate ownership and coordinate intentionally |155| Blocking IO inside latency-sensitive async paths | Offload or separate blocking work clearly |156| Giant global app state for all IDE capabilities | Split state by capability and ownership |157| Over-abstracting lifetimes and generics too early | Keep APIs concrete until a real abstraction appears |158| Detached background task with no cancellation path | Assign owner manager and implement stop/join cleanup |159160## Connected Skills161162- `technical-context-discovery` - follow existing Rust and Tauri conventions before editing163- `code-review` - validate correctness, boundaries, and runtime behavior