[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71NV2W7DWZB6545PPKD1YRF":3,"skill-same:01M71NV2W7DWZB6545PPKD1YRF":80},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":15,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":57,"ownerHtmlUrl":58,"ownerBlogUrl":59,"ownerDescription":6,"updatedAt":60,"install":61,"resources":74},"01M71NV2W7DWZB6545PPKD1YRF","rust-patterns",null,"Use when writing or reviewing Rust code and idiom is in question: ownership and borrowing, Result and ? error propagation, traits, concurrency and crate layout. A patterns catalogue with good vs bad examples; for an end-to-end build persona, use rust-engineer.","monoes\u002Fmonomind","monoes","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F276744696?v=4","01M71KWF37AJ2NJBP3KWBVSDGT","01M71KWF4CSF8ADH0M6HA09VD2",23,"MIT","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Frust-patterns\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Frust-patterns\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"rust","patterns","rust patterns","error","engineering","ownership","build","propagation","github","examples","use","bad","borrowing","for","standards","context","coding","writing","question","engineer","2026-11-10 10:56:23",false,"---\nname: rust-patterns\ndescription: \"Use when writing or reviewing Rust code and idiom is in question: ownership and borrowing, Result and ? error propagation, traits, concurrency and crate layout. A patterns catalogue with good vs bad examples; for an end-to-end build persona, use rust-engineer.\"\ntags: [\"engineering\",\"rust\",\"coding-standards\"]\ntools: [\"monograph_query\",\"monograph_context\"]\nlicense: MIT\nsource: https:\u002F\u002Fgithub.com\u002Faffaan-m\u002FECC\nsource_path: \"skills\u002Frust-patterns\"\nsource_commit: bf70150eb2df8070024e5bdf08e4aa08959e2735\n---\n# Rust Development Patterns\n\nIdiomatic Rust patterns and best practices for building safe, performant, and maintainable applications.\n\n## When to Use\n\n- Writing new Rust code\n- Reviewing Rust code\n- Refactoring existing Rust code\n- Designing crate structure and module layout\n\n## How It Works\n\nThis skill enforces idiomatic Rust conventions across six key areas: ownership and borrowing to prevent data races at compile time, `Result`\u002F`?` error propagation with `thiserror` for libraries and `anyhow` for applications, enums and exhaustive pattern matching to make illegal states unrepresentable, traits and generics for zero-cost abstraction, safe concurrency via `Arc\u003CMutex\u003CT>>`, channels, and async\u002Fawait, and minimal `pub` surfaces organized by domain.\n\n## Core Principles\n\n### 1. Ownership and Borrowing\n\nRust's ownership system prevents data races and memory bugs at compile time.\n\n```rust\n\u002F\u002F Good: Pass references when you don't need ownership\nfn process(data: &[u8]) -> usize {\n    data.len()\n}\n\n\u002F\u002F Good: Take ownership only when you need to store or consume\nfn store(data: Vec\u003Cu8>) -> Record {\n    Record { payload: data }\n}\n\n\u002F\u002F Bad: Cloning unnecessarily to avoid borrow checker\nfn process_bad(data: &Vec\u003Cu8>) -> usize {\n    let cloned = data.clone(); \u002F\u002F Wasteful — just borrow\n    cloned.len()\n}\n```\n\n### Use `Cow` for Flexible Ownership\n\n```rust\nuse std::borrow::Cow;\n\nfn normalize(input: &str) -> Cow\u003C'_, str> {\n    if input.contains(' ') {\n        Cow::Owned(input.replace(' ', \"_\"))\n    } else {\n        Cow::Borrowed(input) \u002F\u002F Zero-cost when no mutation needed\n    }\n}\n```\n\n## Error Handling\n\n### Use `Result` and `?` — Never `unwrap()` in Production\n\n```rust\n\u002F\u002F Good: Propagate errors with context\nuse anyhow::{Context, Result};\n\nfn load_config(path: &str) -> Result\u003CConfig> {\n    let content = std::fs::read_to_string(path)\n        .with_context(|| format!(\"failed to read config from {path}\"))?;\n    let config: Config = toml::from_str(&content)\n        .with_context(|| format!(\"failed to parse config from {path}\"))?;\n    Ok(config)\n}\n\n\u002F\u002F Bad: Panics on error\nfn load_config_bad(path: &str) -> Config {\n    let content = std::fs::read_to_string(path).unwrap(); \u002F\u002F Panics!\n    toml::from_str(&content).unwrap()\n}\n```\n\n### Library Errors with `thiserror`, Application Errors with `anyhow`\n\n```rust\n\u002F\u002F Library code: structured, typed errors\nuse thiserror::Error;\n\n#[derive(Debug, Error)]\npub enum StorageError {\n    #[error(\"record not found: {id}\")]\n    NotFound { id: String },\n    #[error(\"connection failed\")]\n    Connection(#[from] std::io::Error),\n    #[error(\"invalid data: {0}\")]\n    InvalidData(String),\n}\n\n\u002F\u002F Application code: flexible error handling\nuse anyhow::{bail, Result};\n\nfn run() -> Result\u003C()> {\n    let config = load_config(\"app.toml\")?;\n    if config.workers == 0 {\n        bail!(\"worker count must be > 0\");\n    }\n    Ok(())\n}\n```\n\n### `Option` Combinators Over Nested Matching\n\n```rust\n\u002F\u002F Good: Combinator chain\nfn find_user_email(users: &[User], id: u64) -> Option\u003CString> {\n    users.iter()\n        .find(|u| u.id == id)\n        .map(|u| u.email.clone())\n}\n\n\u002F\u002F Bad: Deeply nested matching\nfn find_user_email_bad(users: &[User], id: u64) -> Option\u003CString> {\n    match users.iter().find(|u| u.id == id) {\n        Some(user) => match &user.email {\n            email => Some(email.clone()),\n        },\n        None => None,\n    }\n}\n```\n\n## Enums and Pattern Matching\n\n### Model States as Enums\n\n```rust\n\u002F\u002F Good: Impossible states are unrepresentable\nenum ConnectionState {\n    Disconnected,\n    Connecting { attempt: u32 },\n    Connected { session_id: String },\n    Failed { reason: String, retries: u32 },\n}\n\nfn handle(state: &ConnectionState) {\n    match state {\n        ConnectionState::Disconnected => connect(),\n        ConnectionState::Connecting { attempt } if *attempt > 3 => abort(),\n        ConnectionState::Connecting { .. } => wait(),\n        ConnectionState::Connected { session_id } => use_session(session_id),\n        ConnectionState::Failed { retries, .. } if *retries \u003C 5 => retry(),\n        ConnectionState::Failed { reason, .. } => log_failure(reason),\n    }\n}\n```\n\n### Exhaustive Matching — No Catch-All for Business Logic\n\n```rust\n\u002F\u002F Good: Handle every variant explicitly\nmatch command {\n    Command::Start => start_service(),\n    Command::Stop => stop_service(),\n    Command::Restart => restart_service(),\n    \u002F\u002F Adding a new variant forces handling here\n}\n\n\u002F\u002F Bad: Wildcard hides new variants\nmatch command {\n    Command::Start => start_service(),\n    _ => {} \u002F\u002F Silently ignores Stop, Restart, and future variants\n}\n```\n\n## Traits and Generics\n\n### Accept Generics, Return Concrete Types\n\n```rust\n\u002F\u002F Good: Generic input, concrete output\nfn read_all(reader: &mut impl Read) -> std::io::Result\u003CVec\u003Cu8>> {\n    let mut buf = Vec::new();\n    reader.read_to_end(&mut buf)?;\n    Ok(buf)\n}\n\n\u002F\u002F Good: Trait bounds for multiple constraints\nfn process\u003CT: Display + Send + 'static>(item: T) -> String {\n    format!(\"processed: {item}\")\n}\n```\n\n### Trait Objects for Dynamic Dispatch\n\n```rust\n\u002F\u002F Use when you need heterogeneous collections or plugin systems\ntrait Handler: Send + Sync {\n    fn handle(&self, request: &Request) -> Response;\n}\n\nstruct Router {\n    handlers: Vec\u003CBox\u003Cdyn Handler>>,\n}\n\n\u002F\u002F Use generics when you need performance (monomorphization)\nfn fast_process\u003CH: Handler>(handler: &H, request: &Request) -> Response {\n    handler.handle(request)\n}\n```\n\n### Newtype Pattern for Type Safety\n\n```rust\n\u002F\u002F Good: Distinct types prevent mixing up arguments\nstruct UserId(u64);\nstruct OrderId(u64);\n\nfn get_order(user: UserId, order: OrderId) -> Result\u003COrder> {\n    \u002F\u002F Can't accidentally swap user and order IDs\n    todo!()\n}\n\n\u002F\u002F Bad: Easy to swap arguments\nfn get_order_bad(user_id: u64, order_id: u64) -> Result\u003COrder> {\n    todo!()\n}\n```\n\n## Structs and Data Modeling\n\n### Builder Pattern for Complex Construction\n\n```rust\nstruct ServerConfig {\n    host: String,\n    port: u16,\n    max_connections: usize,\n}\n\nimpl ServerConfig {\n    fn builder(host: impl Into\u003CString>, port: u16) -> ServerConfigBuilder {\n        ServerConfigBuilder { host: host.into(), port, max_connections: 100 }\n    }\n}\n\nstruct ServerConfigBuilder { host: String, port: u16, max_connections: usize }\n\nimpl ServerConfigBuilder {\n    fn max_connections(mut self, n: usize) -> Self { self.max_connections = n; self }\n    fn build(self) -> ServerConfig {\n        ServerConfig { host: self.host, port: self.port, max_connections: self.max_connections }\n    }\n}\n\n\u002F\u002F Usage: ServerConfig::builder(\"localhost\", 8080).max_connections(200).build()\n```\n\n## Iterators and Closures\n\n### Prefer Iterator Chains Over Manual Loops\n\n```rust\n\u002F\u002F Good: Declarative, lazy, composable\nlet active_emails: Vec\u003CString> = users.iter()\n    .filter(|u| u.is_active)\n    .map(|u| u.email.clone())\n    .collect();\n\n\u002F\u002F Bad: Imperative accumulation\nlet mut active_emails = Vec::new();\nfor user in &users {\n    if user.is_active {\n        active_emails.push(user.email.clone());\n    }\n}\n```\n\n### Use `collect()` with Type Annotation\n\n```rust\n\u002F\u002F Collect into different types\nlet names: Vec\u003C_> = items.iter().map(|i| &i.name).collect();\nlet lookup: HashMap\u003C_, _> = items.iter().map(|i| (i.id, i)).collect();\nlet combined: String = parts.iter().copied().collect();\n\n\u002F\u002F Collect Results — short-circuits on first error\nlet parsed: Result\u003CVec\u003Ci32>, _> = strings.iter().map(|s| s.parse()).collect();\n```\n\n## Concurrency\n\n### `Arc\u003CMutex\u003CT>>` for Shared Mutable State\n\n```rust\nuse std::sync::{Arc, Mutex};\n\nlet counter = Arc::new(Mutex::new(0));\nlet handles: Vec\u003C_> = (0..10).map(|_| {\n    let counter = Arc::clone(&counter);\n    std::thread::spawn(move || {\n        let mut num = counter.lock().expect(\"mutex poisoned\");\n        *num += 1;\n    })\n}).collect();\n\nfor handle in handles {\n    handle.join().expect(\"worker thread panicked\");\n}\n```\n\n### Channels for Message Passing\n\n```rust\nuse std::sync::mpsc;\n\nlet (tx, rx) = mpsc::sync_channel(16); \u002F\u002F Bounded channel with backpressure\n\nfor i in 0..5 {\n    let tx = tx.clone();\n    std::thread::spawn(move || {\n        tx.send(format!(\"message {i}\")).expect(\"receiver disconnected\");\n    });\n}\ndrop(tx); \u002F\u002F Close sender so rx iterator terminates\n\nfor msg in rx {\n    println!(\"{msg}\");\n}\n```\n\n### Async with Tokio\n\n```rust\nuse tokio::time::Duration;\n\nasync fn fetch_with_timeout(url: &str) -> Result\u003CString> {\n    let response = tokio::time::timeout(\n        Duration::from_secs(5),\n        reqwest::get(url),\n    )\n    .await\n    .context(\"request timed out\")?\n    .context(\"request failed\")?;\n\n    response.text().await.context(\"failed to read body\")\n}\n\n\u002F\u002F Spawn concurrent tasks\nasync fn fetch_all(urls: Vec\u003CString>) -> Vec\u003CResult\u003CString>> {\n    let handles: Vec\u003C_> = urls.into_iter()\n        .map(|url| tokio::spawn(async move {\n            fetch_with_timeout(&url).await\n        }))\n        .collect();\n\n    let mut results = Vec::with_capacity(handles.len());\n    for handle in handles {\n        results.push(handle.await.unwrap_or_else(|e| panic!(\"spawned task panicked: {e}\")));\n    }\n    results\n}\n```\n\n## Unsafe Code\n\n### When Unsafe Is Acceptable\n\n```rust\n\u002F\u002F Acceptable: FFI boundary with documented invariants (Rust 2024+)\n\u002F\u002F\u002F # Safety\n\u002F\u002F\u002F `ptr` must be a valid, aligned pointer to an initialized `Widget`.\nunsafe fn widget_from_raw\u003C'a>(ptr: *const Widget) -> &'a Widget {\n    \u002F\u002F SAFETY: caller guarantees ptr is valid and aligned\n    unsafe { &*ptr }\n}\n\n\u002F\u002F Acceptable: Performance-critical path with proof of correctness\n\u002F\u002F SAFETY: index is always \u003C len due to the loop bound\nunsafe { slice.get_unchecked(index) }\n```\n\n### When Unsafe Is NOT Acceptable\n\n```rust\n\u002F\u002F Bad: Using unsafe to bypass borrow checker\n\u002F\u002F Bad: Using unsafe for convenience\n\u002F\u002F Bad: Using unsafe without a Safety comment\n\u002F\u002F Bad: Transmuting between unrelated types\n```\n\n## Module System and Crate Structure\n\n### Organize by Domain, Not by Type\n\n```text\nmy_app\u002F\n├── src\u002F\n│   ├── main.rs\n│   ├── lib.rs\n│   ├── auth\u002F          # Domain module\n│   │   ├── mod.rs\n│   │   ├── token.rs\n│   │   └── middleware.rs\n│   ├── orders\u002F        # Domain module\n│   │   ├── mod.rs\n│   │   ├── model.rs\n│   │   └── service.rs\n│   └── db\u002F            # Infrastructure\n│       ├── mod.rs\n│       └── pool.rs\n├── tests\u002F             # Integration tests\n├── benches\u002F           # Benchmarks\n└── Cargo.toml\n```\n\n### Visibility — Expose Minimally\n\n```rust\n\u002F\u002F Good: pub(crate) for internal sharing\npub(crate) fn validate_input(input: &str) -> bool {\n    !input.is_empty()\n}\n\n\u002F\u002F Good: Re-export public API from lib.rs\npub mod auth;\npub use auth::AuthMiddleware;\n\n\u002F\u002F Bad: Making everything pub\npub fn internal_helper() {} \u002F\u002F Should be pub(crate) or private\n```\n\n## Tooling Integration\n\n### Essential Commands\n\n```bash\n# Build and check\ncargo build\ncargo check              # Fast type checking without codegen\ncargo clippy             # Lints and suggestions\ncargo fmt                # Format code\n\n# Testing\ncargo test\ncargo test -- --nocapture    # Show println output\ncargo test --lib             # Unit tests only\ncargo test --test integration # Integration tests only\n\n# Dependencies\ncargo audit              # Security audit\ncargo tree               # Dependency tree\ncargo update             # Update dependencies\n\n# Performance\ncargo bench              # Run benchmarks\n```\n\n## Quick Reference: Rust Idioms\n\n| Idiom | Description |\n|-------|-------------|\n| Borrow, don't clone | Pass `&T` instead of cloning unless ownership is needed |\n| Make illegal states unrepresentable | Use enums to model valid states only |\n| `?` over `unwrap()` | Propagate errors, never panic in library\u002Fproduction code |\n| Parse, don't validate | Convert unstructured data to typed structs at the boundary |\n| Newtype for type safety | Wrap primitives in newtypes to prevent argument swaps |\n| Prefer iterators over loops | Declarative chains are clearer and often faster |\n| `#[must_use]` on Results | Ensure callers handle return values |\n| `Cow` for flexible ownership | Avoid allocations when borrowing suffices |\n| Exhaustive matching | No wildcard `_` for business-critical enums |\n| Minimal `pub` surface | Use `pub(crate)` for internal APIs |\n\n## Anti-Patterns to Avoid\n\n```rust\n\u002F\u002F Bad: .unwrap() in production code\nlet value = map.get(\"key\").unwrap();\n\n\u002F\u002F Bad: .clone() to satisfy borrow checker without understanding why\nlet data = expensive_data.clone();\nprocess(&original, &data);\n\n\u002F\u002F Bad: Using String when &str suffices\nfn greet(name: String) { \u002F* should be &str *\u002F }\n\n\u002F\u002F Bad: Box\u003Cdyn Error> in libraries (use thiserror instead)\nfn parse(input: &str) -> Result\u003CData, Box\u003Cdyn std::error::Error>> { todo!() }\n\n\u002F\u002F Bad: Ignoring must_use warnings\nlet _ = validate(input); \u002F\u002F Silently discarding a Result\n\n\u002F\u002F Bad: Blocking in async context\nasync fn bad_async() {\n    std::thread::sleep(Duration::from_secs(1)); \u002F\u002F Blocks the executor!\n    \u002F\u002F Use: tokio::time::sleep(Duration::from_secs(1)).await;\n}\n```\n\n**Remember**: If it compiles, it's probably correct — but only if you avoid `unwrap()`, minimize `unsafe`, and let the type system work for you.\n","# Rust Development Patterns\n\nIdiomatic Rust patterns and best practices for building safe, performant, and maintainable applications.\n\n## When to Use\n\n- Writing new Rust code\n- Reviewing Rust code\n- Refactoring existing Rust code\n- Designing crate structure and module layout\n\n## How It Works\n\nThis skill enforces idiomatic Rust conventions across six key areas: ownership and borrowing to prevent data races at compile time, `Result`\u002F`?` error propagation with `thiserror` for libraries and `anyhow` for applications, enums and exhaustive pattern matching to make illegal states unrepresentable, traits and generics for zero-cost abstraction, safe concurrency via `Arc\u003CMutex\u003CT>>`, channels, and async\u002Fawait, and minimal `pub` surfaces organized by domain.\n\n## Core Principles\n\n### 1. Ownership and Borrowing\n\nRust's ownership system prevents data races and memory bugs at compile time.\n\n```rust\n\u002F\u002F Good: Pass references when you don't need ownership\nfn process(data: &[u8]) -> usize {\n    data.len()\n}\n\n\u002F\u002F Good: Take ownership only when you need to store or consume\nfn store(data: Vec\u003Cu8>) -> Record {\n    Record { payload: data }\n}\n\n\u002F\u002F Bad: Cloning unnecessarily to avoid borrow checker\nfn process_bad(data: &Vec\u003Cu8>) -> usize {\n    let cloned = data.clone(); \u002F\u002F Wasteful — just borrow\n    cloned.len()\n}\n```\n\n### Use `Cow` for Flexible Ownership\n\n```rust\nuse std::borrow::Cow;\n\nfn normalize(input: &str) -> Cow\u003C'_, str> {\n    if input.contains(' ') {\n        Cow::Owned(input.replace(' ', \"_\"))\n    } else {\n        Cow::Borrowed(input) \u002F\u002F Zero-cost when no mutation needed\n    }\n}\n```\n\n## Error Handling\n\n### Use `Result` and `?` — Never `unwrap()` in Production\n\n```rust\n\u002F\u002F Good: Propagate errors with context\nuse anyhow::{Context, Result};\n\nfn load_config(path: &str) -> Result\u003CConfig> {\n    let content = std::fs::read_to_string(path)\n        .with_context(|| format!(\"failed to read config from {path}\"))?;\n    let config: Config = toml::from_str(&content)\n        .with_context(|| format!(\"failed to parse config from {path}\"))?;\n    Ok(config)\n}\n\n\u002F\u002F Bad: Panics on error\nfn load_config_bad(path: &str) -> Config {\n    let content = std::fs::read_to_string(path).unwrap(); \u002F\u002F Panics!\n    toml::from_str(&content).unwrap()\n}\n```\n\n### Library Errors with `thiserror`, Application Errors with `anyhow`\n\n```rust\n\u002F\u002F Library code: structured, typed errors\nuse thiserror::Error;\n\n#[derive(Debug, Error)]\npub enum StorageError {\n    #[error(\"record not found: {id}\")]\n    NotFound { id: String },\n    #[error(\"connection failed\")]\n    Connection(#[from] std::io::Error),\n    #[error(\"invalid data: {0}\")]\n    InvalidData(String),\n}\n\n\u002F\u002F Application code: flexible error handling\nuse anyhow::{bail, Result};\n\nfn run() -> Result\u003C()> {\n    let config = load_config(\"app.toml\")?;\n    if config.workers == 0 {\n        bail!(\"worker count must be > 0\");\n    }\n    Ok(())\n}\n```\n\n### `Option` Combinators Over Nested Matching\n\n```rust\n\u002F\u002F Good: Combinator chain\nfn find_user_email(users: &[User], id: u64) -> Option\u003CString> {\n    users.iter()\n        .find(|u| u.id == id)\n        .map(|u| u.email.clone())\n}\n\n\u002F\u002F Bad: Deeply nested matching\nfn find_user_email_bad(users: &[User], id: u64) -> Option\u003CString> {\n    match users.iter().find(|u| u.id == id) {\n        Some(user) => match &user.email {\n            email => Some(email.clone()),\n        },\n        None => None,\n    }\n}\n```\n\n## Enums and Pattern Matching\n\n### Model States as Enums\n\n```rust\n\u002F\u002F Good: Impossible states are unrepresentable\nenum ConnectionState {\n    Disconnected,\n    Connecting { attempt: u32 },\n    Connected { session_id: String },\n    Failed { reason: String, retries: u32 },\n}\n\nfn handle(state: &ConnectionState) {\n    match state {\n        ConnectionState::Disconnected => connect(),\n        ConnectionState::Connecting { attempt } if *attempt > 3 => abort(),\n        ConnectionState::Connecting { .. } => wait(),\n        ConnectionState::Connected { session_id } => use_session(session_id),\n        ConnectionState::Failed { retries, .. } if *retries \u003C 5 => retry(),\n        ConnectionState::Failed { reason, .. } => log_failure(reason),\n    }\n}\n```\n\n### Exhaustive Matching — No Catch-All for Business Logic\n\n```rust\n\u002F\u002F Good: Handle every variant explicitly\nmatch command {\n    Command::Start => start_service(),\n    Command::Stop => stop_service(),\n    Command::Restart => restart_service(),\n    \u002F\u002F Adding a new variant forces handling here\n}\n\n\u002F\u002F Bad: Wildcard hides new variants\nmatch command {\n    Command::Start => start_service(),\n    _ => {} \u002F\u002F Silently ignores Stop, Restart, and future variants\n}\n```\n\n## Traits and Generics\n\n### Accept Generics, Return Concrete Types\n\n```rust\n\u002F\u002F Good: Generic input, concrete output\nfn read_all(reader: &mut impl Read) -> std::io::Result\u003CVec\u003Cu8>> {\n    let mut buf = Vec::new();\n    reader.read_to_end(&mut buf)?;\n    Ok(buf)\n}\n\n\u002F\u002F Good: Trait bounds for multiple constraints\nfn process\u003CT: Display + Send + 'static>(item: T) -> String {\n    format!(\"processed: {item}\")\n}\n```\n\n### Trait Objects for Dynamic Dispatch\n\n```rust\n\u002F\u002F Use when you need heterogeneous collections or plugin systems\ntrait Handler: Send + Sync {\n    fn handle(&self, request: &Request) -> Response;\n}\n\nstruct Router {\n    handlers: Vec\u003CBox\u003Cdyn Handler>>,\n}\n\n\u002F\u002F Use generics when you need performance (monomorphization)\nfn fast_process\u003CH: Handler>(handler: &H, request: &Request) -> Response {\n    handler.handle(request)\n}\n```\n\n### Newtype Pattern for Type Safety\n\n```rust\n\u002F\u002F Good: Distinct types prevent mixing up arguments\nstruct UserId(u64);\nstruct OrderId(u64);\n\nfn get_order(user: UserId, order: OrderId) -> Result\u003COrder> {\n    \u002F\u002F Can't accidentally swap user and order IDs\n    todo!()\n}\n\n\u002F\u002F Bad: Easy to swap arguments\nfn get_order_bad(user_id: u64, order_id: u64) -> Result\u003COrder> {\n    todo!()\n}\n```\n\n## Structs and Data Modeling\n\n### Builder Pattern for Complex Construction\n\n```rust\nstruct ServerConfig {\n    host: String,\n    port: u16,\n    max_connections: usize,\n}\n\nimpl ServerConfig {\n    fn builder(host: impl Into\u003CString>, port: u16) -> ServerConfigBuilder {\n        ServerConfigBuilder { host: host.into(), port, max_connections: 100 }\n    }\n}\n\nstruct ServerConfigBuilder { host: String, port: u16, max_connections: usize }\n\nimpl ServerConfigBuilder {\n    fn max_connections(mut self, n: usize) -> Self { self.max_connections = n; self }\n    fn build(self) -> ServerConfig {\n        ServerConfig { host: self.host, port: self.port, max_connections: self.max_connections }\n    }\n}\n\n\u002F\u002F Usage: ServerConfig::builder(\"localhost\", 8080).max_connections(200).build()\n```\n\n## Iterators and Closures\n\n### Prefer Iterator Chains Over Manual Loops\n\n```rust\n\u002F\u002F Good: Declarative, lazy, composable\nlet active_emails: Vec\u003CString> = users.iter()\n    .filter(|u| u.is_active)\n    .map(|u| u.email.clone())\n    .collect();\n\n\u002F\u002F Bad: Imperative accumulation\nlet mut active_emails = Vec::new();\nfor user in &users {\n    if user.is_active {\n        active_emails.push(user.email.clone());\n    }\n}\n```\n\n### Use `collect()` with Type Annotation\n\n```rust\n\u002F\u002F Collect into different types\nlet names: Vec\u003C_> = items.iter().map(|i| &i.name).collect();\nlet lookup: HashMap\u003C_, _> = items.iter().map(|i| (i.id, i)).collect();\nlet combined: String = parts.iter().copied().collect();\n\n\u002F\u002F Collect Results — short-circuits on first error\nlet parsed: Result\u003CVec\u003Ci32>, _> = strings.iter().map(|s| s.parse()).collect();\n```\n\n## Concurrency\n\n### `Arc\u003CMutex\u003CT>>` for Shared Mutable State\n\n```rust\nuse std::sync::{Arc, Mutex};\n\nlet counter = Arc::new(Mutex::new(0));\nlet handles: Vec\u003C_> = (0..10).map(|_| {\n    let counter = Arc::clone(&counter);\n    std::thread::spawn(move || {\n        let mut num = counter.lock().expect(\"mutex poisoned\");\n        *num += 1;\n    })\n}).collect();\n\nfor handle in handles {\n    handle.join().expect(\"worker thread panicked\");\n}\n```\n\n### Channels for Message Passing\n\n```rust\nuse std::sync::mpsc;\n\nlet (tx, rx) = mpsc::sync_channel(16); \u002F\u002F Bounded channel with backpressure\n\nfor i in 0..5 {\n    let tx = tx.clone();\n    std::thread::spawn(move || {\n        tx.send(format!(\"message {i}\")).expect(\"receiver disconnected\");\n    });\n}\ndrop(tx); \u002F\u002F Close sender so rx iterator terminates\n\nfor msg in rx {\n    println!(\"{msg}\");\n}\n```\n\n### Async with Tokio\n\n```rust\nuse tokio::time::Duration;\n\nasync fn fetch_with_timeout(url: &str) -> Result\u003CString> {\n    let response = tokio::time::timeout(\n        Duration::from_secs(5),\n        reqwest::get(url),\n    )\n    .await\n    .context(\"request timed out\")?\n    .context(\"request failed\")?;\n\n    response.text().await.context(\"failed to read body\")\n}\n\n\u002F\u002F Spawn concurrent tasks\nasync fn fetch_all(urls: Vec\u003CString>) -> Vec\u003CResult\u003CString>> {\n    let handles: Vec\u003C_> = urls.into_iter()\n        .map(|url| tokio::spawn(async move {\n            fetch_with_timeout(&url).await\n        }))\n        .collect();\n\n    let mut results = Vec::with_capacity(handles.len());\n    for handle in handles {\n        results.push(handle.await.unwrap_or_else(|e| panic!(\"spawned task panicked: {e}\")));\n    }\n    results\n}\n```\n\n## Unsafe Code\n\n### When Unsafe Is Acceptable\n\n```rust\n\u002F\u002F Acceptable: FFI boundary with documented invariants (Rust 2024+)\n\u002F\u002F\u002F # Safety\n\u002F\u002F\u002F `ptr` must be a valid, aligned pointer to an initialized `Widget`.\nunsafe fn widget_from_raw\u003C'a>(ptr: *const Widget) -> &'a Widget {\n    \u002F\u002F SAFETY: caller guarantees ptr is valid and aligned\n    unsafe { &*ptr }\n}\n\n\u002F\u002F Acceptable: Performance-critical path with proof of correctness\n\u002F\u002F SAFETY: index is always \u003C len due to the loop bound\nunsafe { slice.get_unchecked(index) }\n```\n\n### When Unsafe Is NOT Acceptable\n\n```rust\n\u002F\u002F Bad: Using unsafe to bypass borrow checker\n\u002F\u002F Bad: Using unsafe for convenience\n\u002F\u002F Bad: Using unsafe without a Safety comment\n\u002F\u002F Bad: Transmuting between unrelated types\n```\n\n## Module System and Crate Structure\n\n### Organize by Domain, Not by Type\n\n```text\nmy_app\u002F\n├── src\u002F\n│   ├── main.rs\n│   ├── lib.rs\n│   ├── auth\u002F          # Domain module\n│   │   ├── mod.rs\n│   │   ├── token.rs\n│   │   └── middleware.rs\n│   ├── orders\u002F        # Domain module\n│   │   ├── mod.rs\n│   │   ├── model.rs\n│   │   └── service.rs\n│   └── db\u002F            # Infrastructure\n│       ├── mod.rs\n│       └── pool.rs\n├── tests\u002F             # Integration tests\n├── benches\u002F           # Benchmarks\n└── Cargo.toml\n```\n\n### Visibility — Expose Minimally\n\n```rust\n\u002F\u002F Good: pub(crate) for internal sharing\npub(crate) fn validate_input(input: &str) -> bool {\n    !input.is_empty()\n}\n\n\u002F\u002F Good: Re-export public API from lib.rs\npub mod auth;\npub use auth::AuthMiddleware;\n\n\u002F\u002F Bad: Making everything pub\npub fn internal_helper() {} \u002F\u002F Should be pub(crate) or private\n```\n\n## Tooling Integration\n\n### Essential Commands\n\n```bash\n# Build and check\ncargo build\ncargo check              # Fast type checking without codegen\ncargo clippy             # Lints and suggestions\ncargo fmt                # Format code\n\n# Testing\ncargo test\ncargo test -- --nocapture    # Show println output\ncargo test --lib             # Unit tests only\ncargo test --test integration # Integration tests only\n\n# Dependencies\ncargo audit              # Security audit\ncargo tree               # Dependency tree\ncargo update             # Update dependencies\n\n# Performance\ncargo bench              # Run benchmarks\n```\n\n## Quick Reference: Rust Idioms\n\n| Idiom | Description |\n|-------|-------------|\n| Borrow, don't clone | Pass `&T` instead of cloning unless ownership is needed |\n| Make illegal states unrepresentable | Use enums to model valid states only |\n| `?` over `unwrap()` | Propagate errors, never panic in library\u002Fproduction code |\n| Parse, don't validate | Convert unstructured data to typed structs at the boundary |\n| Newtype for type safety | Wrap primitives in newtypes to prevent argument swaps |\n| Prefer iterators over loops | Declarative chains are clearer and often faster |\n| `#[must_use]` on Results | Ensure callers handle return values |\n| `Cow` for flexible ownership | Avoid allocations when borrowing suffices |\n| Exhaustive matching | No wildcard `_` for business-critical enums |\n| Minimal `pub` surface | Use `pub(crate)` for internal APIs |\n\n## Anti-Patterns to Avoid\n\n```rust\n\u002F\u002F Bad: .unwrap() in production code\nlet value = map.get(\"key\").unwrap();\n\n\u002F\u002F Bad: .clone() to satisfy borrow checker without understanding why\nlet data = expensive_data.clone();\nprocess(&original, &data);\n\n\u002F\u002F Bad: Using String when &str suffices\nfn greet(name: String) { \u002F* should be &str *\u002F }\n\n\u002F\u002F Bad: Box\u003Cdyn Error> in libraries (use thiserror instead)\nfn parse(input: &str) -> Result\u003CData, Box\u003Cdyn std::error::Error>> { todo!() }\n\n\u002F\u002F Bad: Ignoring must_use warnings\nlet _ = validate(input); \u002F\u002F Silently discarding a Result\n\n\u002F\u002F Bad: Blocking in async context\nasync fn bad_async() {\n    std::thread::sleep(Duration::from_secs(1)); \u002F\u002F Blocks the executor!\n    \u002F\u002F Use: tokio::time::sleep(Duration::from_secs(1)).await;\n}\n```\n\n**Remember**: If it compiles, it's probably correct — but only if you avoid `unwrap()`, minimize `unsafe`, and let the type system work for you.\n",{"name":5,"tags":44,"tools":46,"source":49,"license":14,"description":7,"source_path":50,"source_commit":51},[23,19,45],"coding-standards",[47,48],"monograph_query","monograph_context","https:\u002F\u002Fgithub.com\u002Faffaan-m\u002FECC","skills\u002Frust-patterns","bf70150eb2df8070024e5bdf08e4aa08959e2735","main","f7cd4595d0f8959822163e14f9787117765c931a","packages\u002F@monomind\u002Fcli\u002Forg-skills\u002Frust-patterns",2,"https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind","https:\u002F\u002Fmonoes.github.io\u002Fmonomind\u002F","https:\u002F\u002Fgithub.com\u002Fmonoes","https:\u002F\u002Fmonoes.me","2026-11-14 03:30:52",{"source":8,"skillName":5,"commands":62,"prompt":72,"zipAvailable":73},[63,66,69],{"tool":64,"command":65},"npx","npx skills add monoes\u002Fmonomind --skill rust-patterns",{"tool":67,"command":68},"bunx","bunx skills add monoes\u002Fmonomind --skill rust-patterns",{"tool":70,"command":71},"pnpm","pnpm dlx skills add monoes\u002Fmonomind --skill rust-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Frust-patterns\u002FSKILL.md",true,[75],{"path":76,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":79,"sourceHtmlUrl":15},"LICENSE.txt","LICENSE","许可证",1071,[81,109,142,168,191,217],{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":85,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":108},"01M71PB3SHWKMNJM6MD65VX8D6","zk-steward","Org role guidance for a ZK steward: engineer zero-knowledge proof systems with circuit design, SNARK vs STARK choice and security review. This is zero-knowledge cryptography, not Zettelkasten note-taking.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fzk-steward\u002FSKILL.md",[],[89,90,91,92,38,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107],"zk","zk steward","steward","zero-knowledge","choice","design","knowledge","impact","query","snark","review","monomind","security review","stark","zettelkasten","cryptography","security","org","blockchain","2026-11-10 13:02:02",{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":113,"sourceHtmlUrl":114,"categories":115,"keywords":126,"publishedAt":108},"01M71PB18SDG28WBKPKJNB814K","writing-plans","Use when you have a spec or requirements for a multi-step coding task and must write an implementation plan before touching code. Produces bite-sized TDD tasks with exact file paths, code and commands for an engineer with zero context.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwriting-plans\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwriting-plans\u002FSKILL.md",[116,121],{"categoryNo":117,"categoryName":118,"taxonomyType":119,"taxonomyTypeDesc":120},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",{"categoryNo":122,"categoryName":123,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[36,127,128,38,129,130,131,132,97,133,134,135,136,137,138,139,140,35,34,141],"writing plans","plans","superpowers","implementation plan","when","you","code","tasks","plan","product","write","commands","paths","suggest","ZeRO",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":85,"licenseFileUrl":146,"sourceHtmlUrl":147,"categories":148,"keywords":152,"publishedAt":108},"01M71PAXFM488X9ARXK0T04TF5","write-spec","Write a feature spec or PRD from a problem statement or feature idea. Use when turning a vague idea or user request into a structured document, scoping a feature with goals and non-goals, defining success metrics and acceptance criteria, or breaking a big ask into a phased spec.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-spec\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-spec\u002FSKILL.md",[149],{"categoryNo":150,"categoryName":151,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000031","产品经理",[137,153,154,155,156,95,157,131,158,159,160,136,161,162,163,164,165,166,29,167],"write spec","spec","user request","problem","acceptance","ask","vague","work","request","scoping","idea","metrics","feature","problem statement","document",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":85,"licenseFileUrl":172,"sourceHtmlUrl":173,"categories":174,"keywords":178,"publishedAt":108},"01M71PASSZY800C0RPEARBS918","write-query","Write optimized SQL for your dialect with best practices. Use when translating a natural-language data need into SQL, building a multi-CTE query with joins and aggregations, optimizing a query against a large partitioned table, or getting dialect-specific syntax for Snowflake, BigQuery, Postgres, etc.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-query\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-query\u002FSKILL.md",[175],{"categoryNo":176,"categoryName":177,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000033","数据分析师",[97,137,179,180,32,181,95,29,131,182,183,184,185,160,27,186,187,188,189,190],"write query","postgres","snowflake","best practices","natural-language","with","multi","sql","https","syntax","plugins","data",{"skillNo":192,"name":193,"nameZh":6,"description":194,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":85,"licenseFileUrl":6,"sourceHtmlUrl":195,"categories":196,"keywords":203,"publishedAt":108},"01M71PAPTX0T3PF6ETFVR96SJJ","workflow-automation","Org role guidance for workflow automation: build and maintain CI\u002FCD definitions in GitHub Actions or equivalent: triggers, jobs, matrices, caching. Covers path filters, dependency caching, parallel jobs, timeouts and fail-fast ordering.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fworkflow-automation\u002FSKILL.md",[197,200],{"categoryNo":198,"categoryName":199,"taxonomyType":119,"taxonomyTypeDesc":120},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":201,"categoryName":202,"taxonomyType":119,"taxonomyTypeDesc":120},"01JBSEEDCAT000000000000023","Skill与智能体开发",[204,205,206,207,32,208,209,210,211,96,212,213,214,97,100,27,25,215,216,187],"Workflow Automation","automation","workflow","parallel","actions","ci","triggers","github actions","maintain","filters","caching","dependency","devops",{"skillNo":218,"name":219,"nameZh":6,"description":220,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":85,"licenseFileUrl":6,"sourceHtmlUrl":221,"categories":222,"keywords":224,"publishedAt":108},"01M71PAM19Z1XTV9NPCFSE2MY8","workflow-architect","Org role guidance for a workflow architect: map full workflow trees for systems, user journeys and agents, covering every branch and failure. Covers discovering workflows from code, handoff contracts, timeouts, recovery paths and observable state.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fworkflow-architect\u002FSKILL.md",[223],{"categoryNo":201,"categoryName":202,"taxonomyType":119,"taxonomyTypeDesc":120},[206,225,226,227,228,229,230,32,231,232,133,233,234,235,100,27,236,237,187,238],"workflow architect","architect","trees","user journeys","branch","planning","map","workflows","architecture","state","leadership","recovery","operations","systems"]