
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/RefCell/OnceCell/OnceLock), I/O streams (Read/Write/BufRead), iterators, Option/Result combinators, threads and mpsc channels, time (Duration/Instant/SystemTime), paths, env, process, fs, net, and module selection decisions. Use when users ask "which std type should I use", compare collection/pointer/string alternatives, design Option/Result chains, choose Cell vs RefCell vs Mutex, work with std threads/channels, or pick the right std module for a task; hand async runtime to rust-concurrency, language semantics to rust-stable, and application-layer concerns to domain skills.
- Installs
- 98
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/full-stack-skills/rust-skills --skill rust-stdlib- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads rust-stdlib automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Rust Standard Library — API Selection and Composition
Authority: Rust Standard Library — the canonical reference. Read
references/std-module-index.mdfor 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
- Picking the right collection (HashMap vs BTreeMap vs Vec vs VecDeque vs LinkedList vs BinaryHeap)
- Choosing the right smart pointer (Box vs Rc vs Arc vs RefCell vs Mutex vs OnceLock)
- Selecting the right string type (String vs &str vs OsString vs PathBuf vs Cow)
- Choosing interior mutability primitive (Cell vs RefCell vs OnceCell vs OnceLock vs LazyLock)
- Designing Option/Result combinator chains (map, and_then, unwrap_or_else, ok_or, transpose)
- Selecting I/O trait (Read vs Write vs BufRead vs Seek vs AsyncRead)
- Choosing iterator pattern (iter vs into_iter vs owning iterator, lazy vs collect)
- Using std concurrency primitives (thread, mpsc, barrier, Once, scoped threads)
- Selecting time API (Duration vs Instant vs SystemTime vs TryFromFloat)
- Cross-platform path handling (Path vs PathBuf, fs, env, process::Command)
⚠️ Prerequisites
- Rust ownership and lifetimes — see
rust-stable - Cargo and project structure — see
rust-cargo-build,rust-workspace
❌ Out of Scope
- Async runtime (Tokio, async-std) →
rust-concurrency - Language semantics (ownership, traits, lifetimes) →
rust-stable - Application-layer concerns (CLI, web, database) → domain skills
- 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
| Type | Order | Lookup | Insert | When |
|---|---|---|---|---|
Vec<T> | insertion | O(n) by value, O(1) by index | O(1) amortized push | Default sequence |
VecDeque<T> | insertion | O(1) front/back | O(1) front/back | Queue, sliding window |
LinkedList<T> | insertion | O(n) | O(1) anywhere with cursor | Almost never; prefer Vec |
BinaryHeap<T> | priority | O(1) peek | O(log n) push/pop | Priority queue |
HashMap<K,V> | none | O(1) avg | O(1) avg | Fast lookup, no order |
BTreeMap<K,V> | sorted | O(log n) | O(log n) | Ordered keys, range queries |
HashSet<T> | none | O(1) avg | O(1) avg | Membership |
BTreeSet<T> | sorted | O(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
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
| Type | Ownership | Thread-safe | Mutability | Use |
|---|---|---|---|---|
Box<T> | Single | Yes | Direct (owned) | Heap allocation, recursive types |
Rc<T> | Shared | No | Immutable only | Reference counting, single-threaded |
Arc<T> | Shared | Yes | Immutable only | Atomic RC, multi-threaded |
Cell<T> | Single | No | Interior (Copy only) | Simple mutable state |
RefCell<T> | Single | No | Interior (borrow check at runtime) | Mutation behind shared ref |
Mutex<T> | Single | Yes | Interior (lock) | Shared mutable state, sync |
RwLock<T> | Single | Yes | Interior (read/write lock) | Many readers, few writers |
OnceLock<T> | Single | Yes | One-time init | Lazy globals, std::sync::OnceLock |
LazyLock<T> | Single | Yes | One-time init, transparent deref | Const-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
| Type | Encoding | Owned? | Use |
|---|---|---|---|
&str | UTF-8 | No | Function params, string literals |
String | UTF-8 | Yes | Owned mutable UTF-8 text |
OsString/OsStr | Platform-native | Yes/No | Environment, process args |
PathBuf/Path | Platform-native | Yes/No | Filesystem paths |
Cow<'a, str> | UTF-8 | Maybe | Zero-copy when possible, owned when needed |
Vec<u8>/&[u8] | Bytes | Yes/No | Binary 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
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());
| Type | Sync? | Use |
|---|---|---|
Cell<T> | No | Copy types only, simple mutation |
RefCell<T> | No | Non-Copy types, single-thread |
OnceCell<T> | No | One-time lazy init |
OnceLock<T> | Yes | One-time lazy init, multi-thread (std 1.70+) |
LazyLock<T> | Yes | Transparent 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
// 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
// ? 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
| Pattern | Code |
|---|---|
| Try parsing, fallback to default | s.parse().unwrap_or(default) |
| Early return on error | let x = result?; |
| Convert Option to Result | opt.ok_or(Error::Missing)? |
| Collect all Results | results.collect::<Result<Vec<_>, _>>() |
| Try all, return first success | `opts.into_iter().find_map( |
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
| Need | Use |
|---|---|
| Read bytes from a source | impl Read (File, Cursor, stdin) |
| Buffered reading (lines, until) | impl BufRead (BufReader wrapping) |
| Write bytes to a destination | impl Write (File, stdout, Vec) |
| Random access | impl Seek (File) |
| Async I/O | tokio::io::AsyncRead/AsyncWrite (rust-concurrency) |
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
| Need | Use |
|---|---|
| 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) |
// 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
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
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
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
| Primitive | Use |
|---|---|
Mutex<T> | Exclusive lock, sync interior mutability |
RwLock<T> | Many readers, few writers |
Arc<T> | Atomic reference counting |
Barrier | Synchronize multiple threads at a point |
Once | One-time initialization |
Condvar | Wait/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
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 elapsedSystemTime— wall-clock, for timestamps (can go backwards!)
Path
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
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
- Identify the need — collection, pointer, string, I/O, iterator, or system interface?
- Apply decision tree — pick from the relevant Part above
- Check MSRV — some APIs (
OnceLock1.70,LazyLock1.80, scoped threads 1.63) need recent stable - Compose with combinators — prefer
Option/Resultchains over explicitmatch - Verify —
cargo check,cargo test,cargo clippy - Hand off — async runtime →
rust-concurrency; unsafe →rust-unsafe-ffi; application concerns → domain skills
Decision Shortcuts
| Question | Answer |
|---|---|
| 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
- Collections Deep Dive
- Smart Pointers
- String Types
- Option/Result Combinators
- I/O Streams
- Iterators
- Std Concurrency
- Process and Filesystem
- Interior Mutability
- Std Module Index
examples/golden-stdlib/: a crate exercising collections, pointers, channels, and iterators
Upstream Sources
FAQ
What does the rust-stdlib skill do?
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/RefCell/OnceCell/OnceLock), I/O streams (Read/Write/BufRead), iterators, Option/Result combinators, threads and mpsc channels, time (Duration/Instant/SystemTime), paths, env, process, fs, net, and module selection decisions. Use when users ask "which std type should I use", compare collection/pointer/string alternatives, design Option/Result chains, choose Cell vs RefCell vs Mutex, work with std threads/channels, or pick the right std module for a task; hand async runtime to rust-concurrency, language semantics to rust-stable, and application-layer concerns to domain skills.
How do I install rust-stdlib?
Run npx skills add https://github.com/full-stack-skills/rust-skills --skill rust-stdlib in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/rust-stdlib/ (personal) or .claude/skills/rust-stdlib/ (project).
Which AI agents can use rust-stdlib?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is rust-stdlib safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains rust-stdlib?
It is published by full-stack-skills in full-stack-skills/rust-skills. It has 98 recorded installs.
More from full-stack-skills/rust-skills
rust-testing
full-stack-skills/rust-skills
Open the skill to read its SKILL.md instructions.
rust-style-clippy
full-stack-skills/rust-skills
Open the skill to read its SKILL.md instructions.
rust-concurrency
full-stack-skills/rust-skills
Open the skill to read its SKILL.md instructions.
rust-performance
full-stack-skills/rust-skills
Open the skill to read its SKILL.md instructions.
rust-code-review
full-stack-skills/rust-skills
Open the skill to read its SKILL.md instructions.
rust-cargo-build
full-stack-skills/rust-skills
Open the skill to read its SKILL.md instructions.
Popular backend & apis skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
entra-app-registration
microsoft/azure-skills
Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.
google-agents-cli-adk-code
google/agents-cli
This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).
embedded-captions
heygen-com/hyperframes
Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.
entra-agent-id
microsoft/azure-skills
Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).
neon
neondatabase/agent-skills
Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.