Skip to content
Back to skills

Rust

BSecurity

Rust is a compiled, memory-safe systems programming language whose toolchain (rustup, rustc, Cargo, Clippy, rustfmt) builds, tests, lints and packages code. Use this skill to install or pin a Rust toolchain, start a crate or a multi-crate Cargo workspace, add dependencies, fix borrow-checker errors, design error handling with Result, gate CI on clippy and fmt, migrate to the 2024 edition, or ship an optimized release binary. Triggers: "set up Rust", "cargo new", "cargo workspace", "fix this b...

  • 155 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 4, 2026
developmentrustgobashgitapi

Works with

  • terminal
  • cli
  • api

Security analysis

B88/100
  • criticalDownloads and executes remote scripts — classic supply chain attack

Pro scans all 2 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add TerminalSkills/skills --skill rust --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Rust?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Rust
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/terminalskills-rust/badge)](https://www.skillsdirectory.com/skills/terminalskills-rust)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: rust
description: >-
  Rust is a compiled, memory-safe systems programming language whose toolchain
  (rustup, rustc, Cargo, Clippy, rustfmt) builds, tests, lints and packages
  code. Use this skill to install or pin a Rust toolchain, start a crate or a
  multi-crate Cargo workspace, add dependencies, fix borrow-checker errors,
  design error handling with Result, gate CI on clippy and fmt, migrate to the
  2024 edition, or ship an optimized release binary. Triggers: "set up Rust",
  "cargo new", "cargo workspace", "fix this borrow checker error", "clippy
  warnings", "migrate to edition 2024", "pin the Rust version", "build a Rust
  CLI".
license: Apache-2.0
compatibility: "Linux, macOS or Windows; rustup with a stable toolchain (examples verified on Rust 1.98.1); edition 2024 needs Rust 1.85+; a C linker (cc on Linux, Xcode CLT on macOS, MSVC build tools on Windows)"
metadata:
  author: terminal-skills
  version: "1.0.0"
  category: development
  tags: ["rust", "cargo", "rustup", "clippy", "systems-programming"]
  repository: https://github.com/rust-lang/rust
---
# Rust — Memory-Safe Systems Language and Cargo Toolchain

## Overview

Rust compiles to native code with no garbage collector; the borrow checker enforces memory and thread safety at compile time. Day-to-day work goes through a small set of tools: `rustup` installs and switches toolchains, `cargo` creates, builds, tests and publishes packages (crates), `clippy` lints, and `rustfmt` formats. Stable releases ship every six weeks; language-level breaking changes are opt-in through editions (2015, 2018, 2021, 2024), set per crate in `Cargo.toml`.

This skill covers the language and toolchain. For web servers use the `axum` or `rocket` skills, for async runtimes `tokio`, for desktop apps `tauri`, for WebAssembly `wasm`.

## Instructions

### Install the toolchain with rustup

```bash
# Install rustup, not a distro rustc package; Debian 13+/Ubuntu 24.04+, Arch and Homebrew ship it
sudo apt install rustup            # or: sudo pacman -S rustup / brew install rustup
rustup default stable
```

On Fedora the DNF package provides only `rustup-init`; run it once to create the proxies and install a toolchain. Homebrew's rustup does not put `rustc`/`cargo` on `PATH`; add `$(brew --prefix rustup)/bin`. Without a package manager, download the installer binary from the official domain and run it as a separate step (on Windows, run `rustup-init.exe` from https://rustup.rs):

```bash
URL=https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init
curl --proto '=https' --tlsv1.2 -sSfo rustup-init $URL
curl --proto '=https' --tlsv1.2 -sSf $URL.sha256 | sha256sum -c -   # must print "./rustup-init: OK"
chmod +x rustup-init
./rustup-init -y --profile minimal -c clippy -c rustfmt
```

rustup puts the proxies (`rustc`, `cargo`, `rustup`) in `~/.cargo/bin`, which must be on `PATH`; toolchains are stored under `~/.rustup/toolchains`. Useful commands:

```bash
rustup update                          # update every installed toolchain and rustup
rustup component add clippy rustfmt    # lint + format tools for the active toolchain
rustup target add wasm32-unknown-unknown aarch64-unknown-linux-gnu
rustc --explain E0382                  # long-form explanation of any error code
```

### Pin the toolchain per project

When half a team is on an old rustc and CI keeps breaking, commit a `rust-toolchain.toml` at the repo root so every developer and CI job uses the same compiler:

```toml
[toolchain]
channel = "1.98.1"
components = ["clippy", "rustfmt"]
```

`rustup show active-toolchain` then prints `1.98.1-x86_64-unknown-linux-gnu (overridden by '.../rust-toolchain.toml')`. rustup downloads the pinned toolchain the first time any `cargo` command runs in the repo, so CI needs only rustup itself. If auto-install is off (`RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable`), run `rustup toolchain install` in the repo; with no argument it installs what the file names. `channel` accepts `stable`, `beta`, `nightly`, `nightly-2026-09-01`, or a version such as `1.85` / `1.98.1`. Separately, declare the minimum supported version (MSRV) in `Cargo.toml` with `rust-version = "1.85"`.

### Create and build a crate

```bash
cargo new invoice-sync            # binary crate: src/main.rs, edition = "2024"
cd invoice-sync
cargo check                       # fast type-check, no codegen — use while editing
cargo build                       # debug build -> target/debug/invoice-sync
cargo run -- --since 2026-09-01   # args after -- go to your program
cargo build --release             # optimized -> target/release/invoice-sync
```

### Manage dependencies

```bash
cargo add serde --features derive      # edits Cargo.toml [dependencies]
cargo add --dev pretty_assertions      # test-only dependency
cargo remove --dev pretty_assertions   # --dev needed: plain remove only looks in [dependencies]
cargo update                           # refresh Cargo.lock within semver ranges
cargo tree --depth 1                   # see what pulled in what
```

Commit `Cargo.lock` for binaries and workspaces. Install Rust-written CLIs with `cargo install --locked ripgrep` so the published lockfile is honored.

### Organize a multi-crate workspace

A virtual workspace root has only a `[workspace]` table. Shared metadata, dependency versions and lints are declared once and inherited:

```toml
[workspace]
resolver = "3"                     # required in a virtual workspace; MSRV-aware resolution
members = []                       # `cargo new crates/<name>` appends each crate

[workspace.package]
edition = "2024"
rust-version = "1.85"

[workspace.dependencies]
thiserror = "2"

[workspace.lints.clippy]
unwrap_used = "warn"

[profile.release]
lto = true
codegen-units = 1
```

Running `cargo new --lib crates/logparse` inside the root appends the crate to `members` and writes `edition.workspace = true` plus `[lints] workspace = true` (the opt-in to the shared lint table). `cargo add thiserror -p logparse` then writes `thiserror.workspace = true`. Path dependencies between members: `cargo add --path crates/logparse -p logscan-cli`.

### Handle errors with Result

Return `Result<T, E>` and propagate with `?`; reserve `panic!`/`unwrap()` for true bugs. Common split: a typed error enum (often via `thiserror`) in libraries, `anyhow::Result` with `.context()` in binaries. Library, `crates/logparse/src/lib.rs`:

```rust
use thiserror::Error;

#[derive(Debug, Error)]
pub enum ParseError {
    #[error("line {line}: expected `LEVEL service: message`")]
    Malformed { line: usize },
    #[error("line {line}: unknown level `{level}`")]
    UnknownLevel { line: usize, level: String },
}

/// Returns `(level, service)` for a line such as `ERROR billing: card declined`.
/// ```
/// assert_eq!(logparse::parse_line("WARN checkout: slow", 1).unwrap(), ("WARN", "checkout"));
/// ```
pub fn parse_line(raw: &str, line: usize) -> Result<(&str, &str), ParseError> {
    let (level, rest) = raw.split_once(' ').ok_or(ParseError::Malformed { line })?;
    let (service, _message) = rest.split_once(": ").ok_or(ParseError::Malformed { line })?;
    match level {
        "INFO" | "WARN" | "ERROR" => Ok((level, service)),
        _ => Err(ParseError::UnknownLevel { line, level: level.to_string() }),
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn unknown_level() {
        let err = super::parse_line("DEBUG billing: retry", 7).map_err(|e| e.to_string());
        assert_eq!(err, Err("line 7: unknown level `DEBUG`".to_string()));
    }
}
```

Binary, `crates/logscan-cli/src/main.rs`, counting ERROR lines per service. A `main` that returns `Err` prints `Error: ...` and exits with status 1:

```rust
use anyhow::{Context, Result};
use std::collections::BTreeMap;

fn main() -> Result<()> {
    let path = std::env::args().nth(1).context("usage: logscan-cli FILE")?;
    let text = std::fs::read_to_string(&path).with_context(|| format!("reading {path}"))?;
    let mut errors: BTreeMap<&str, usize> = BTreeMap::new();
    for (i, raw) in text.lines().enumerate() {
        let (level, service) = logparse::parse_line(raw, i + 1)?;
        if level == "ERROR" {
            *errors.entry(service).or_default() += 1;
        }
    }
    for (service, count) in &errors {
        println!("{service:<12} {count}");
    }
    Ok(())
}
```

### Test, lint and format

Unit tests sit next to the code in a `#[cfg(test)] mod tests`, integration tests in `tests/`, and code blocks in `///` doc comments run as doctests. The first, third and fourth commands below are the usual CI gate:

```bash
cargo test --workspace                     # unit + integration + doctests
cargo test -p logparse unknown             # filter by crate and test-name substring
cargo fmt --all -- --check                 # fail if anything is unformatted
cargo clippy --workspace --all-targets -- -D warnings
```

### Migrate to a newer edition

```bash
cargo update
cargo fix --edition        # rewrites code that would break under the next edition
# then set edition = "2024" in Cargo.toml (or [workspace.package])
cargo build && cargo test
cargo fmt
```

`cargo fix` refuses to run on a dirty git tree; commit first. It cannot fix everything: macros, doctests and generated code may need manual edits.

## Examples

### Example 1: Scaffold a log-scanning workspace with CI checks

**User:** "Set up a Rust workspace with a parsing library and a CLI that counts ERROR lines per service in our app.log. Make clippy and fmt pass."

```bash
mkdir logscan && cd logscan
# write the [workspace] Cargo.toml from "Organize a multi-crate workspace"
cargo new --lib crates/logparse
cargo new crates/logscan-cli
cargo add thiserror -p logparse
cargo add anyhow -p logscan-cli
cargo add --path crates/logparse -p logscan-cli
# write lib.rs and main.rs from "Handle errors with Result"
cargo fmt --all                     # rewraps the two long lines in parse_line
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo build --release
./target/release/logscan-cli app.log
```

Result, with a five-line `app.log`:

```text
$ cat app.log
INFO api: started on :8080
ERROR billing: card declined for invoice 4471
ERROR billing: Stripe timeout after 30s
WARN checkout: slow response 2.4s
ERROR checkout: 502 from upstream
$ ./target/release/logscan-cli app.log
billing      2
checkout     1
```

`cargo test` passes the `unknown_level` unit test and the `parse_line` doctest; clippy is clean. A file whose first line is `NOTICE api: cache warmed` makes the CLI print ``Error: line 1: unknown level `NOTICE` `` and exit with status 1.

### Example 2: Fix a "borrow of moved value" error

**User:** "cargo build fails with E0382 in main.rs, recipients was moved."

```rust
fn notify(recipients: Vec<String>) -> usize {
    recipients.len()
}

fn main() {
    let recipients = vec!["ops@lindqvist-freight.se".to_string(), "oncall@lindqvist-freight.se".to_string()];
    let sent = notify(recipients);                      // ownership moves here
    println!("sent {sent} alerts to {}", recipients.join(", ")); // E0382
}
```

The compiler reports `error[E0382]: borrow of moved value: recipients` and suggests cloning. Cloning works but copies the vector; the function only reads, so borrow a slice instead:

```rust
fn notify(recipients: &[String]) -> usize {
    recipients.len()
}

fn main() {
    let recipients = vec!["ops@lindqvist-freight.se".to_string(), "oncall@lindqvist-freight.se".to_string()];
    let sent = notify(&recipients);
    println!("sent {sent} alerts to {}", recipients.join(", "));
}
```

`cargo run` prints `sent 2 alerts to ops@lindqvist-freight.se, oncall@lindqvist-freight.se` and `cargo clippy -- -D warnings` is clean.

## Guidelines

- Run `cargo check` in the edit loop; full builds and `--release` are much slower. Put build output on a fast disk — `target/` grows to several GB.
- Prefer borrowing (`&T`, `&str`, `&[T]`) in function parameters; take ownership only when the function stores or consumes the value. Reach for `.clone()` last.
- Avoid `unwrap()`/`expect()` in library and request-handling code; the `clippy::unwrap_used` lint (shown above) enforces this.
- `unsafe` blocks turn off compile-time guarantees; keep them small, document the invariant in a `// SAFETY:` comment, and never use them to silence the borrow checker.
- A new stable release lands every six weeks and may add Clippy lints, so `-D warnings` can start failing on `rustup update`; pinning the toolchain avoids surprise CI breaks.
- Before adding a crate, check its downloads, maintenance and license on crates.io; every dependency runs `build.rs` scripts and proc-macros with your user's permissions at build time.
- Rust is a poor fit for quick throwaway scripts or when the team must ship a CRUD prototype this week — compile times and the learning curve are real costs.

Files in this skill

  • SKILL.md12.6 KB
  • _scores.json1.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…