full-stack-skills/rust-skills

rust-stdlib

Select and compose Rust standard-library APIs — collections (HashMap/BTreeMap/Vec/VecDeque/LinkedList/BinaryHeap), smart pointers (Box/Rc/Arc/RefCell/Mutex/OnceLock/LazyLock), string types (String/&str/OsString/PathBuf/Cow), interior mutability (Cell/RefCel…

소스 보기
원본 Skill 문서

원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.

Rust Standard Library — API Selection and Composition

Authority: Rust Standard Library — the canonical reference. Read references/std-module-index.md for the full module map.

This skill owns choosing and composing std APIs: which collection, which smart pointer, which string type, which I/O trait, which iterator pattern. It does not own language semantics (rust-stable), async runtime (rust-concurrency), or application-layer concerns (the domain skills).

Capability Boundaries

✅ Strengths

  1. Picking the right collection (HashMap vs BTreeMap vs Vec vs VecDeque vs LinkedList vs BinaryHeap)
  2. Choosing the right smart pointer (Box vs Rc vs Arc vs RefCell vs Mutex vs OnceLock)
  3. Selecting the right string type (String vs &str vs OsString vs PathBuf vs Cow)
  4. Choosing interior mutability primitive (Cell vs RefCell vs OnceCell vs OnceLock vs LazyLock)
  5. Designing Option/Result combinator chains (map, andthen, unwraporelse, okor, transpose)
  6. Selecting I/O trait (Read vs Write vs BufRead vs Seek vs AsyncRead)
  7. Choosing iterator pattern (iter vs into_iter vs owning iterator, lazy vs collect)
  8. Using std concurrency primitives (thread, mpsc, barrier, Once, scoped threads)
  9. Selecting time API (Duration vs Instant vs SystemTime vs TryFromFloat)
  10. Cross-platform path handling (Path vs PathBuf, fs, env, process::Command)

⚠️ Prerequisites

  1. Rust ownership and lifetimes — see rust-stable
  2. Cargo and project structure — see rust-cargo-build, rust-workspace

❌ Out of Scope

  1. Async runtime (Tokio, async-std) → rust-concurrency
  2. Language semantics (ownership, traits, lifetimes) → rust-stable
  3. Application-layer concerns (CLI, web, database) → domain skills
  4. Unsafe and FFI → rust-unsafe-ffi

Data Privacy

This skill does not collect, store, or transmit user data.


Part 1: Collections

Decision tree

Need a collection?
│
├─ Key-value lookup?
│   ├─ Order doesn't matter, fast lookup → HashMap<K, V>
│   ├─ Need sorted iteration / range queries → BTreeMap<K, V>
│   └─ Tiny (<20 entries), linear scan OK → Vec<(K, V)> with .iter().find()
│
├─ Sequence?
│   ├─ Append/pop from end → Vec<T>
│   ├─ Push/pop from both ends → VecDeque<T>
│   ├─ Insert/remove from middle frequently → LinkedList<T> (rare; usually Vec is better)
│   └─ Priority queue / always-min-first → BinaryHeap<T>
│
├─ Set?
│   ├─ Fast membership, no order → HashSet<T>
│   └─ Sorted iteration → BTreeSet<T>
│
└─ No collection needed — use Vec<T>

Quick reference

TypeOrderLookupInsertWhen
Vec<T>insertionO(n) by value, O(1) by indexO(1) amortized pushDefault sequence
VecDeque<T>insertionO(1) front/backO(1) front/backQueue, sliding window
LinkedList<T>insertionO(n)O(1) anywhere with cursorAlmost never; prefer Vec
BinaryHeap<T>priorityO(1) peekO(log n) push/popPriority queue
HashMap<K,V>noneO(1) avgO(1) avgFast lookup, no order
BTreeMap<K,V>sortedO(log n)O(log n)Ordered keys, range queries
HashSet<T>noneO(1) avgO(1) avgMembership
BTreeSet<T>sortedO(log n)O(log n)Sorted membership

See references/collections.md for allocation behavior, hasher selection (BuildHasherDefault/FxHashMap), and entry API patterns.

Entry API — avoid double lookup

rust
use std::collections::HashMap;

let mut counts: HashMap<&str, u32> = HashMap::new();
for word in text.split_whitespace() {
    *counts.entry(word).or_insert(0) += 1;   // single hash, no double lookup
}

Part 2: Smart Pointers

Decision tree

Need shared/indirected ownership?
│
├─ Single owner, heap-allocated → Box<T>
│
├─ Multiple readers, single thread → Rc<T>
│   └─ Need to mutate through shared ref → Rc<RefCell<T>>
│
├─ Multiple readers, multiple threads → Arc<T>
│   └─ Need to mutate through shared ref → Arc<Mutex<T>> or Arc<RwLock<T>>
│
├─ Need lazy one-time init → OnceLock<T> (sync) or once_cell::Lazy
│
└─ Need interior mutability (no shared ownership)?
    ├─ Copy type, simple → Cell<T>
    ├─ Non-Copy, complex → RefCell<T> (single thread)
    └─ Multi-thread → Mutex<T> or RwLock<T>

Quick reference

TypeOwnershipThread-safeMutabilityUse
Box<T>SingleYesDirect (owned)Heap allocation, recursive types
Rc<T>SharedNoImmutable onlyReference counting, single-threaded
Arc<T>SharedYesImmutable onlyAtomic RC, multi-threaded
Cell<T>SingleNoInterior (Copy only)Simple mutable state
RefCell<T>SingleNoInterior (borrow check at runtime)Mutation behind shared ref
Mutex<T>SingleYesInterior (lock)Shared mutable state, sync
RwLock<T>SingleYesInterior (read/write lock)Many readers, few writers
OnceLock<T>SingleYesOne-time initLazy globals, std::sync::OnceLock
LazyLock<T>SingleYesOne-time init, transparent derefConst-ish globals (Rust 1.80+)

See references/smart-pointers.md for trade-offs, drop ordering, and Weak<T> for cycles.


Part 3: String Types

Decision tree

Working with text?
│
├─ Function parameter → &str (always)
├─ Owned, mutable, UTF-8 → String
├─ Borrowed, UTF-8, with mixed owned/borrowed → Cow<'a, str>
├─ OS path (Windows/Unix native) → OsString (owned) / OsStr (borrowed)
├─ Filesystem path → PathBuf (owned) / Path (borrowed)
└─ Bytes that might not be UTF-8 → Vec<u8> / &[u8]

Quick reference

TypeEncodingOwned?Use
&strUTF-8NoFunction params, string literals
StringUTF-8YesOwned mutable UTF-8 text
OsString/OsStrPlatform-nativeYes/NoEnvironment, process args
PathBuf/PathPlatform-nativeYes/NoFilesystem paths
Cow<'a, str>UTF-8MaybeZero-copy when possible, owned when needed
Vec<u8>/&[u8]BytesYes/NoBinary data, non-UTF-8

See references/string-types.md for conversion (.to_string() vs .to_owned() vs .into()), Cow usage, and &str slicing safety (is_char_boundary).


Part 4: Interior Mutability

Cell vs RefCell vs OnceCell

rust
use std::cell::{Cell, RefCell, OnceCell};

// Cell: only for Copy types, no borrow checking
let counter = Cell::new(0);
counter.set(counter.get() + 1);

// RefCell: for non-Copy types, runtime borrow check (panics on double borrow)
let cache = RefCell::new(HashMap::new());
cache.borrow_mut().insert("k", 42);

// OnceCell: one-time initialization
static CONFIG: OnceCell<Config> = OnceCell::new();
let cfg = CONFIG.get_or_init(|| Config::load());
TypeSync?Use
Cell<T>NoCopy types only, simple mutation
RefCell<T>NoNon-Copy types, single-thread
OnceCell<T>NoOne-time lazy init
OnceLock<T>YesOne-time lazy init, multi-thread (std 1.70+)
LazyLock<T>YesTransparent lazy init (std 1.80+)

See references/interior-mutability.md for panic-safety (RefCell double-borrow), choose-Cell-vs-RefCell, and Atomic* for multi-thread.


Part 5: Option and Result Combinators

Option combinators

rust
// map: transform inner value
name.map(|n| n.to_uppercase())                    // Option<String>

// and_then: chain fallible operations
id.and_then(|i| db.lookup(i))                     // Option<User>

// unwrap_or / unwrap_or_else: provide default
port.unwrap_or(8080)
port.unwrap_or_else(|| env::var("PORT").unwrap_or("8080").parse().unwrap())

// ok_or / ok_or_else: convert Option to Result
user.ok_or(Error::NotFound)?
user.ok_or_else(|| Error::UserMissing(id))?

// filter, is_some, is_some_and
age.filter(|&a| a >= 18)
opt.is_some_and(|x| x > 0)

// transpose: swap Option<Result> → Result<Option>
let x: Result<Option<i32>, _> = Some("5").parse::<i32>().map(Some);

Result combinators

rust
// ? for propagation (prefer over explicit match)
fn load() -> Result<Config, Error> { Ok(parse(file_read()?)?) }

// map_err: convert error type
file_read().map_err(|e| Error::Io(e))?

// map: transform success value
parse(s).map(|n| n * 2)

// and_then: chain fallible
validate(input).and_then(process)

// or_else / or: fallback on error
primary.or_else(|_| fallback())

Common patterns

PatternCode
Try parsing, fallback to defaults.parse().unwrap_or(default)
Early return on errorlet x = result?;
Convert Option to Resultopt.ok_or(Error::Missing)?
Collect all Resultsresults.collect::<Result<Vec<_>, _>>()
Try all, return first success`opts.intoiter().findmap(oo.try_it().ok())`

See references/option-result-combinators.md for the full combinator table and refactor patterns.


Part 6: I/O Streams

Trait hierarchy

Read ────┐
         ├─ BufRead (adds buffering, lines())
Write ───┘
Seek (random access)

Choosing

NeedUse
Read bytes from a sourceimpl Read (File, Cursor, stdin)
Buffered reading (lines, until)impl BufRead (BufReader wrapping)
Write bytes to a destinationimpl Write (File, stdout, Vec)
Random accessimpl Seek (File)
Async I/Otokio::io::AsyncRead/AsyncWrite (rust-concurrency)
rust
use std::io::{BufRead, BufReader, Read, Write};
use std::fs::File;

let f = File::open("log.txt")?;          // impl Read
let reader = BufReader::new(f);          // wrap for BufRead
for line in reader.lines() {             // BufRead::lines
    println!("{}", line?);
}

See references/io-streams.md for Cursor<Vec<u8>>, error handling (io::Result), and converting between sync and async.


Part 7: Iterators

Choosing

NeedUse
Borrow elements.iter()Iterator<Item = &T>
Mutably borrow.iter_mut()Iterator<Item = &mut T>
Consume.into_iter()Iterator<Item = T>
Index pairs.iter().enumerate()
Filter`.filter(\x\*x > 0)`
Transform`.map(\x\x * 2)`
Flat`.flat_map(\x\x.iter())`
Collect to Vec.collect::<Vec<_>>()
Collect to HashMap.collect::<HashMap<_, _>>() (from (K, V) tuples)
First match`.find(\x\*x == 5)`
Any/all`.any(\x\*x > 0), .all(\x\*x > 0)`
Group/sum.sum::<i32>(), .product(), `.fold(0, \a, b\a + b)`
rust
// Borrowed iteration is the default
let v = vec![1, 2, 3];
for x in &v { /* x: &i32 */ }      // .iter()
for x in &mut v { /* x: &mut i32 */ }
for x in v { /* x: i32, v consumed */ }

See references/iterators.md for custom iterators (impl Iterator), lazy evaluation, and zero-cost abstractions.


Part 8: Std Concurrency

The standard library provides threads, channels, and sync primitives. For async, see rust-concurrency.

Threads

rust
use std::thread;
use std::time::Duration;

let handle = thread::spawn(|| {
    thread::sleep(Duration::from_millis(500));
    "result"
});
let r = handle.join().unwrap();   // wait, get result

Scoped threads (Rust 1.63+) — borrow without 'static

rust
let mut data = vec![1, 2, 3];
thread::scope(|s| {
    s.spawn(|| { data[0] += 1; });
    s.spawn(|| { data[1] += 1; });
});   // all threads joined here; data borrow ends

mpsc channels

rust
use std::sync::mpsc;
use std::thread;

let (tx, rx) = mpsc::channel();
thread::spawn(move || {
    tx.send(42).unwrap();
});
println!("{}", rx.recv().unwrap());

Sync primitives

PrimitiveUse
Mutex<T>Exclusive lock, sync interior mutability
RwLock<T>Many readers, few writers
Arc<T>Atomic reference counting
BarrierSynchronize multiple threads at a point
OnceOne-time initialization
CondvarWait/notify
Atomic* (AtomicUsize, AtomicBool, ...)Lock-free counters, flags

See references/std-concurrency.md for Arc<Mutex<T>> patterns, poison recovery, and when to graduate to Tokio.


Part 9: Time, Path, Process

Time

rust
use std::time::{Duration, Instant, SystemTime};

let start = Instant::now();
expensive_op();
println!("took {:?}", start.elapsed());   // Duration

let five_secs = Duration::from_secs(5);
let mixed = Duration::new(5, 500_000_000);  // 5.5s

let now = SystemTime::now();
let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH)?;
  • Duration — span of time (no specific moment)
  • Instant — monotonic moment, for measuring elapsed
  • SystemTime — wall-clock, for timestamps (can go backwards!)

Path

rust
use std::path::{Path, PathBuf};

let p = Path::new("/usr/bin/foo");
let stem = p.file_stem();      // "foo"
let ext = p.extension();       // "foo" → None; "foo.txt" → "txt"

let joined = PathBuf::from("/usr").join("bin").join("foo");
let parent = p.parent();       // "/usr/bin"

Always use Path/PathBuf for filesystem paths — never String. Cross-platform safe.

Process

rust
use std::process::Command;

let output = Command::new("ls")
    .arg("-l")
    .arg("/")
    .output()?;          // waits, returns Output
println!("{}", String::from_utf8_lossy(&output.stdout));

// Stream stdin/stdout
use std::process::Stdio;
let mut child = Command::new("cat")
    .stdin(Stdio::piped())
    .stdout(Stdio::piped())
    .spawn()?;

See references/process-and-fs.md for Command exit codes, signal handling, and fs module (read, write, create_dir, metadata).


Workflow

  1. Identify the need — collection, pointer, string, I/O, iterator, or system interface?
  2. Apply decision tree — pick from the relevant Part above
  3. Check MSRV — some APIs (OnceLock 1.70, LazyLock 1.80, scoped threads 1.63) need recent stable
  4. Compose with combinators — prefer Option/Result chains over explicit match
  5. Verifycargo check, cargo test, cargo clippy
  6. Hand off — async runtime → rust-concurrency; unsafe → rust-unsafe-ffi; application concerns → domain skills

Decision Shortcuts

QuestionAnswer
Default collection?Vec<T>
Need key-value lookup?HashMap (unordered) or BTreeMap (sorted)
Shared ownership?Rc (single-thread) or Arc (multi-thread)
Mutable shared state?RefCell (single) or Mutex/RwLock (multi)
String parameter?&str always
File path?Path / PathBuf
Lazy global?OnceLock (1.70+) or LazyLock (1.80+)
Iterate borrowed?.iter()
Two-way queue?VecDeque
Priority queue?BinaryHeap

Resources

Upstream Sources

같은 저장소의 Skills

더 많은 Skills

모든 Skills
full-stack-skills
커뮤니티

rust-api-design

Design Rust library APIs that follow the Rust API Guidelines — naming (C-CASE, C-CONV, C-GETTER), interop traits (C-COMMON-TRAITS, C-CONVERT, C-ITER, C-SERDE), predictability (C-INTUITIVE, C-CONST), flexibility (C-GENERIC, C-NEWTYPE, C-EXT), type safety (C-BOOL, C-NONZERO, C-WRAPPER, C-STR), dependability (C-PANIC, C-UNWRAP), debuggability (C-DEBUG), and future-proofing (C-SEALED, C-STRUCT-FIELD, C-NON-EXHAUSTIVE). Use when users design a public crate API, choose between generics/concrete/newtype, decide trait bounds, hide implementation, avoid breakage, or ask "what is idiomatic Rust API design"; hand semver and publish workflow to rust-semver, lint config to rust-style-clippy, and in-crate layout to rust-module-layout.

설치 수
1
GitHub Stars
5
업데이트
9월 19일
full-stack-skills
커뮤니티

rust-by-example

Show Rust patterns through short compilable examples — type conversions (From/Into/TryFrom/as/Deref), flow control (if let/while let/match/loop), functions and closures (Fn/FnMut/FnOnce, captures), modules (mod/use/pub/super/self), generics and traits (bounds/associated types/trait objects), error handling (?/Result/thiserror/anyhow), attributes (derive/cfg/inline/allow), unsafe (raw pointers/unions/ABI), procedural macros (derive/attribute/function-like), and inline asm. Use when users ask "how do I write X in Rust", need a concrete pattern with copy-pasteable code, or are migrating from Java/Python/Go/C++ and want the Rust equivalent; hand architecture decisions to rust-api-design/rust-workspace, std API selection to rust-stdlib, and async runtime to rust-concurrency.

설치 수
1
GitHub Stars
5
업데이트
9월 19일
full-stack-skills
커뮤니티

rust-cargo-build

Configure, operate, diagnose, and automate Cargo for Rust packages and workspaces. Cover manifests and targets, commands, dependency resolution and features, profiles, build scripts, configuration and environment variables, caches and build diagnostics, cross-compilation, registries, packaging, publishing, metadata, CI reproducibility, and stable-versus-nightly feature gates. Use for Cargo.toml, Cargo.lock, .cargo/config.toml, cargo build/check/run/tree/metadata/package/publish, resolver or feature problems, build output and performance, private registries, and beginner Cargo workflows. Route crate selection and supply-chain audits to rust-dependencies, workspace topology to rust-workspace, test design to rust-testing, documentation design to rust-documentation, lint policy to rust-style-clippy, and API compatibility decisions to rust-semver.

설치 수
1
GitHub Stars
5
업데이트
9월 19일
full-stack-skills
커뮤니티

rust-cli

Design, implement, test, and release production Rust command-line applications, including command contracts, subcommands, configuration precedence, stdin/stdout/stderr, exit codes, file safety, daemon IPC, terminal handling, packaging, and process-level tests. Use when users ask for a Rust CLI, command parser, clap integration, Unix-style pipelines, daemon clients, PTY/TUI behavior, shell completion, or CLI release engineering.

설치 수
1
GitHub Stars
5
업데이트
9월 19일