Skip to content
rust-lang/rustlings (opens in a new tab)

A well-structured learning platform with solid Cargo discipline and CI, but undermined by thin documentation and modest guardrails against agent mishaps.

Rust★ 63,30340 open issuesMIT License
Overall score: 75 out of 100
Holding

last scored 2026-06-21 · both lenses

Readiness lenses

The same repo, two ways: how ready it is for an AI coding agent, and for a human newcomer. Switch lenses to see each one's score and checks.

How ready the repo is for an AI coding agent to read, build, and operate it.

75 / 100

16 of 38 checks passed across 6 categories.

  • Machine Orientation

    72

    README is purely marketing material with no build/run commands; AGENTS.md is absent; but Cargo.toml, CONTRIBUTING.md, and CLI structure (src/cli.rs, src/main.rs, src/dev.rs) clearly expose entry points and development workflows.

    The repo provides clear, verifiable build and test infrastructure through Cargo.toml (workspace, dependencies, lints all explicit), working CI/CD (rust.yml with `cargo test`, `cargo fmt`, `cargo clippy`, `cargo dev check`), and a well-structured CLI with documented subcommands (Init, Run, CheckAll, Reset, Hint, Dev). Exercise metadata is machine-readable in rustlings-macros/info.toml with format_version, welcome/final messages, and per-exercise hint/test/skip flags. CONTRIBUTING.md documents the exercise-addition convention explicitly (naming, solution pairing, metadata schema). However, the README delegates entirely to an external website and contains zero commands; no AGENTS.md or equivalent machine-oriented guide exists to tell an agent how to navigate this repo's actual purpose (a learning tool that ships exercises, solutions, and a CLI binary). An agent can infer build/test/run from Cargo.toml and CI, but not from the stated orientation layer.

  • Reproducible Setup

    78

    Strong Cargo setup with pinned lockfile and explicit Rust version, but README lacks build/run instructions and no container alternative exists.

    Rustlings has a committed Cargo.lock file pinning all transitive dependencies (verified), explicit rust-version = "1.88" in Cargo.toml, and workspace-wide pinned dependency versions (anyhow = "1", clap = { version = "4", ...}). CI (rust.yml) runs tests across three OS targets with cargo commands (cargo test --workspace, cargo clippy). However, the README provides no explicit build or run instructions—it redirects to an external website for "setup", leaving an agent to infer the command pipeline. No dev container, Dockerfile, or docker-compose exist as fallbacks. The project has a dev-Cargo.toml for development context and a custom cargo alias (cargo dev), but neither is documented in the README.

  • Code Navigability

    72

    Clear module layout and naming with well-defined responsibilities, but inconsistent type annotations and undocumented module boundaries limit an agent's ability to confidently traverse complex state mutations.

    The repository exhibits solid conventional structure: a single Rust binary with clear top-level module partitions (cli.rs, cmd.rs, exercise.rs, app_state.rs, watch.rs, info_file.rs, etc.), each file ~100–500 LOC with focused responsibility. The 286-file count is almost entirely exercises (23 categories × 2–6 exercises + solutions mirroring them), not source clutter. Cargo.toml declares workspace-wide lints forbidding unsafe code and enforcing strict Clippy checks. However, critical navigability gaps exist: RunnableExercise and Exercise are separate abstractions without documented type relationship; app_state.rs mutates internal state via mutable methods without clear invariant documentation; the watch loop (watch.rs) coordinates across notify_event, state, and terminal_event submodules, but inter-module data flow is implicit; and generic trait bounds in exercise.rs:run() use const generics (FORCE_STRICT_CLIPPY) that are not immediately type-clear on call sites. No architecture doc, llms.txt, or module-level comments explain the state machine.

  • Verification Surface

    78

    Solid CI with explicit test, lint, and format checks across platforms; tests are exercise-verification integrated and pass automatically, but lack explicit test result visibility in logs and integration tests are sparse.

    The repository provides two GitHub Actions workflows that machine-readably close the feedback loop: rust.yml runs clippy (deny warnings), rustfmt (format check), cargo test across three OS platforms (ubuntu, windows, macos), and a custom `cargo dev check` with --require-solutions. Cargo.toml explicitly forbids unsafe_code and unstable_features at the workspace level; clippy lints are configured in [workspace.lints.clippy]. Tests exist (detected=yes): exercises like 17_tests/ contain test files, and the exercise verification system in src/exercise.rs compiles, tests (if test=true in metadata), and runs clippy before marking completion. A cmd.rs module wraps cargo invocations and captures output. However, the test surface has three material gaps: (1) no explicit per-exercise test result logging or summary in CI output visible to an agent, (2) no dedicated integration test suite (tests/test_exercises is excluded from workspace), and (3) no type-checking CI step separate from build (rustc inference is implicit in cargo build/test).

  • Agent Safety

    72

    A learning platform with low secrets exposure risk, but lacks defensive guardrails around destructive operations (reset, init) and agent-read metadata surfaces.

    The repository is a Rust educational exercise platform with no committed `.env` file (gitignore correctly excludes `.rustlings-state.txt`), no hardcoded credentials detected, and no `.env.example` present. However, destructive operations like `rustlings reset` and `rustlings init` have no confirmation prompts or reversibility safeguards, and the `info.toml` metadata file (agent-readable, unsanitized) directly influences runtime behavior with no injection prevention (e.g., hint text, exercise names, and paths flow into terminal output and file operations without escaping).

  • Context Economy

    72

    Exercise and solution files are clearly separated and well-organized; the repo leverages embedded files and a macro system to minimize noise, but carries ~140 small exercise/solution files that could bloat context unpredictably.

    The repository uses `rustlings-macros::include_files!()` to embed exercises and solutions at compile time, keeping them out of the runtime file tree (src/embedded.rs). Exercises are organized into 23 topic directories (00_intro through 23_conversions), each with a README.md and typically 2–6 small .rs files. The Cargo.toml explicitly lists `/exercises/`, `/solutions/`, and `/src/` in the `include` directive, making the package boundaries explicit. However, the file tree contains ~140 exercise and solution .rs files across both directories—individual exercises are small (20–100 LOC typically, based on intro1.rs and solutions/intro1.rs), but an agent reading the full tree will encounter repetitive structure and many near-identical placeholder files, consuming token budget without proportional signal gain. The .gitignore correctly excludes `target/` and compiled artifacts, and `Cargo.lock` is pinned. No linguist markers or vendored bulk are present, and no explicitly marked generated files exist outside the macro system.

  • Machine Orientation

    4 checks passed5 problems found

    • mediumAgent instructions file

      AGENTS.md / CLAUDE.md is the direct, machine-read channel for entry points and conventions.

      Fix: Add an AGENTS.md naming the entry points, the build/test commands, and the house conventions.

    • lowllms.txt present

      An llms.txt is the emerging machine-orientation standard — a curated map for LLMs.

      Fix: Add an llms.txt pointing at the key docs and entry points.

    • lowArchitecture doc

      An ARCHITECTURE doc hands an agent the module map instead of making it infer one.

      Fix: Add an ARCHITECTURE.md describing the major components and how they fit.

    • lowREADME shows usage

      A usage/example section tells an agent how the project is actually invoked.

      Fix: Add a Usage or Examples section to the README with a runnable snippet.

    • lowExamples directory

      An examples/ directory gives an agent runnable, copyable references for the API.

      Fix: Add an examples/ directory with small, runnable usage samples.

    • README present — An agent reconstructs what the repo is and how to work in it from the README first.
    • Repository description set — The one-line description is the fastest orientation signal an agent reads.
    • Topics set — GitHub topics situate the repo's domain and stack for an agent at a glance.
    • Contribution conventions are written down — A contributor guide is where an agent learns the branch, commit, and review conventions it must follow.
  • Reproducible Setup

    1 check passed5 problems found

    • mediumRuntime / toolchain pinned

      An unpinned runtime makes an agent guess the version a clean environment needs.

      Fix: Pin the runtime with .nvmrc / .tool-versions / an engines field / packageManager.

    • mediumContainer or dev-container

      A Dockerfile / compose / devcontainer removes 'works on my machine' from setup.

      Fix: Add a Dockerfile, a compose file, or a .devcontainer so the environment is declared, not assumed.

    • mediumREADME documents setup

      Explicit install/setup steps are what let an agent go from clone to running.

      Fix: Add a Setup/Install section with the exact commands to install and run.

    • lowEnv template present

      A .env.example tells an agent which configuration keys it must supply to run.

      Fix: Ship a .env.example listing every required key with placeholder values.

    • lowDev container

      A .devcontainer gives an agent a one-command, fully-declared environment.

      Fix: Add a .devcontainer so the toolchain is declared, not assumed.

    • Lockfile committed — Without a lockfile two clones can resolve different dependency trees — the build isn't reproducible.
  • Code Navigability

    1 check passed3 problems found

    • low.editorconfig present

      An .editorconfig keeps whitespace and encoding consistent, so diffs stay legible.

      Fix: Add an .editorconfig pinning indentation, charset, and final-newline.

    • lowFormatter configured

      A formatter config (Prettier/Biome/rustfmt/…) keeps style uniform across the tree.

      Fix: Add a formatter (Prettier, Biome, rustfmt, …) and commit its config.

    • lowTyped public API

      A declared `types` entry gives an agent typed signatures to anchor an edit on.

      Fix: Ship type declarations and point package.json `types`/`typings` at them.

    • Conventional source layout — A recognised src/ · lib/ · app/ layout lets an agent localise code without spelunking.
  • Verification Surface

    3 checks passed4 problems found

    • mediumTest command defined

      A `test` script is the documented, discoverable way to run the suite.

      Fix: Add a `test` script (package.json / Makefile / Taskfile) that runs the suite.

    • lowLint command defined

      A linter an agent can run catches a class of mistakes before they ship.

      Fix: Add a `lint` script and a linter config.

    • lowTypecheck command

      A typecheck script lets an agent catch type errors before they ship.

      Fix: Add a `typecheck` script (e.g. `tsc --noEmit`).

    • lowBuild command

      A documented build command is the discoverable way for an agent to produce artifacts.

      Fix: Add a `build` script that produces the distributable.

    • Tests present — Runnable tests are the ground truth an agent checks its own edits against.
    • CI configured — Readable CI is the feedback loop an agent reads to know what 'green' means here.
    • Task runner present — A Makefile / Taskfile / justfile gives an agent a single index of the project's commands.
  • Agent Safety

    4 checks passed4 problems found

    • medium.gitignore covers env files

      An ignore rule for .env is what keeps the next careless commit from leaking secrets.

      Fix: Add `.env` (and `.env.*`) to .gitignore.

    • mediumSecurity policy

      A SECURITY.md is where an autonomous security agent reads this repo's rules before acting on it.

      Fix: Add a SECURITY.md stating the disclosure channel and the repo's security rules.

    • lowCODEOWNERS present

      CODEOWNERS marks the 'don't touch without review' zones an agent should respect.

      Fix: Add a CODEOWNERS file marking the sensitive paths.

    • lowAutomated dependency updates

      Dependabot / Renovate keeps dependencies patched without a human in the loop.

      Fix: Enable Dependabot or Renovate.

    • No committed .env — A tracked real .env hands secrets to anything — including an agent — that reads the repo.
    • No exposed secrets — Secret-shaped literals in tracked files are a live credential leak.
    • .gitignore present — A .gitignore is the first guard against an agent committing secrets or build junk.
    • License makes the code reusable — Without a license an agent cannot safely copy, redistribute, or vendor any of this code.
  • Context Economy

    3 checks passed1 problem found

    • lowGenerated / vendored files marked

      A .gitattributes linguist marker tells tools (and agents) what to skip.

      Fix: Mark generated/vendored paths in .gitattributes (linguist-generated / linguist-vendored).

    • Dependencies not vendored in — A committed node_modules / vendor tree drowns the real signal an agent needs.
    • Build output not committed — Generated dist/ · build/ output is noise an agent has to read past.
    • No oversized source file — A single file in the hundreds of KB blows past an agent's effective context window.

Where the grip slips

  1. mediumReproducible Setup+2 pts if fixed

    README lacks explicit build and run instructions

    The README only mentions a website URL for setup details. An agent cannot determine the exact command to build or run the project from the repository alone, requiring external navigation.

    Fix: Add a Setup or Installation section to README with commands like: 'cargo build --release' and 'cargo run -- <args>', or 'cargo install --path .'

  2. mediumVerification Surface+2 pts if fixed

    No dedicated integration test suite in CI

    The directory tests/test_exercises exists but is excluded from the workspace. There is no CI job that explicitly runs tests on the exercise verification flow itself, only implicit tests via 'cargo dev check'. An agent cannot see evidence that the exercise-runner logic is tested end-to-end.

    Fix: Add a tests/ directory with integration tests for the exercise system (e.g., verify that exercises with test=true in info.toml pass when solved, fail when unsolved). Add a CI job that runs 'cargo test --test '*' to surface these results.

  3. highAgent Safety+1 pts if fixed

    No confirmation prompts on destructive operations

    `rustlings reset` (src/main.rs, Command::Reset) and `rustlings init` (src/init.rs) perform irreversible filesystem operations (removing state, rewriting exercise files) without user confirmation or undo capability. An agent executing these blindly could corrupt or wipe user progress.

    Fix: Add explicit confirmation prompts before `init()` and `reset_current_exercise()` that require typed acknowledgment (e.g., 'yes' or exercise name). Log operation summaries to a recoverable location.

  4. highAgent Safety+1 pts if fixed

    Unsanitized metadata surfaces (hint, exercise name, paths) in terminal output

    Exercise hints, names, and directory paths from `info.toml` are embedded into terminal output (src/exercise.rs, src/main.rs) and file operations without validation or escaping. A malicious or corrupted `info.toml` could inject ANSI codes, control sequences, or path traversal payloads read by an agent.

    Fix: Validate and sanitize all `info.toml` fields at parse time: restrict exercise names to `[a-z0-9_]+`, validate paths against a safe base directory, and escape hint text for terminal output. Add a test that malformed `info.toml` entries are rejected.

  5. highMachine Orientation+1 pts if fixed

    README is marketing-only, contains no build/test/run commands or entry-point orientation

    The README (6 lines) redirects all substantive information to an external website (rustlings.rust-lang.org). It does not state how to build the CLI binary, run tests, initialize exercises, or invoke subcommands. An agent reading only the README will not know this is a Rust CLI binary or how to interact with it.

    Fix: Add a 'Getting Started' section to README with: `cargo build --release` for the binary, `cargo test` for the test suite, `rustlings init` to initialize exercises, and a brief list of key commands (`run`, `hint`, `reset`, `check-all`). Explicitly note that the repo contains both exercises and a CLI tool.

  6. highMachine Orientation+1 pts if fixed

    No AGENTS.md or equivalent machine-readable orientation document

    Best practice for AI-agent readiness is an AGENTS.md or CLAUDE.md that concisely states entry points, build steps, test invocation, repo structure, and conventions. This repo has no such file. An agent must infer everything from Cargo.toml, .github/workflows, and scattered source files.

    Fix: Create AGENTS.md with: (1) Purpose: 'A Rust CLI tool and exercise suite for Rust beginners.' (2) Build: `cargo build --release` (binary in target/release/rustlings). (3) Test: `cargo test --workspace`. (4) Development: `cargo dev check`, `cargo dev new <path>`. (5) Key files: Cargo.toml (workspace), rustlings-macros/info.toml (exercise metadata), src/main.rs (entry point). (6) Structure: /exercises (incomplete exercise files), /solutions (solutions), /src (CLI tool).

  7. lowReproducible Setup+1 pts if fixed

    No container (devcontainer, Dockerfile, or compose) alternative

    While Cargo/Rust toolchain is pinned, no container configuration exists to guarantee the same Rust compiler version across environments without relying on rustup.

    Fix: Add a .devcontainer/devcontainer.json or Dockerfile specifying rust:1.88 (or later stable) to eliminate host-environment variance.

  8. lowReproducible Setup+1 pts if fixed

    Dev tools (cargo dev) not documented as a discovery path

    A custom cargo dev alias exists in .cargo/config.toml but is not surfaced in README, so an agent may not discover the development workflow (dev check, dev new, etc.).

    Fix: Document the cargo dev workflow in a DEVELOPMENT.md or in the README's contribution section, linking to dev subcommands.

  9. mediumCode Navigability+1 pts if fixed

    Undocumented module coordination in watch subsystem

    watch.rs spawns watcher threads and coordinates events across notify_event.rs, state.rs, and terminal_event.rs, but module re-exports and data-flow contracts are not explicit. An agent must trace three submodules to understand event propagation to AppState mutations.

    Fix: Add module-level docs in watch/mod.rs explaining event flow (notify → watch_event_sender → run_watch → watch_state) with a one-line summary of each submodule's responsibility and its public API contract.

  10. highCode Navigability+1 pts if fixed

    Implicit RunnableExercise and Exercise relationship

    Both exercise.rs:Exercise and info_file.rs:ExerciseInfo implement RunnableExercise trait, but the trait's purpose, which implementations are used where, and the path from ExerciseInfo → Exercise are not documented. An agent editing run() may edit the wrong impl.

    Fix: Add trait-level doc comment to RunnableExercise explaining its role as a polymorphic interface used by both info-time and runtime representations; add a note in Exercise::from() or app_state.rs construction showing the conversion flow.

  11. mediumCode Navigability+1 pts if fixed

    No documented invariants for AppState mutable state

    app_state.rs mutates current_exercise_ind, exercises[].done, n_done, and state_file concurrently with editor and file writes. Rules for when these must be synchronized, what lock-free operations are safe, and what order state changes must follow are implicit.

    Fix: Add a struct-level doc comment to AppState listing the invariants (e.g., 'n_done must equal count of exercises with done=true', 'state_file write must follow all mutations before returning').

  12. lowVerification Surface+1 pts if fixed

    Test output summary not machine-parseable in logs

    The CI runs 'cargo test --workspace' but does not capture or summarize test counts, pass/fail breakdown, or flakiness metrics in a machine-readable format (e.g., JUnit XML or a structured summary). An agent must parse raw cargo output to determine overall test health.

    Fix: Use cargo's --format=json or pipe test output to a summary tool (e.g., cargo-nextest with --reporter=json) and upload results as artifacts or post as PR comments for reproducible agent verification.

  13. mediumContext Economy+1 pts if fixed

    Large count of small exercise files without directory-level summaries

    The exercises/ and solutions/ trees contain ~140 individual .rs files spread across 23 directories. While each is small, an agent reading the full tree encounters significant repetition and structural noise—each directory has a README but no single-file index or manifest that would let an agent skip to the essentials.

    Fix: Add a top-level exercises/MANIFEST.md or use .gitattributes to mark exercise/solution directories as non-core for context-aware tools; alternatively, document in the main README that exercises/* and solutions/* are auto-generated from rustlings-macros/info.toml and should be scanned only when needed.

  14. mediumAgent Safety

    No SECURITY.md or explicit agent safety boundary documentation

    No SECURITY.md file exists; agent-safe operations and 'no-touch' boundaries (e.g., don't modify `/dev/*` paths, don't trust unsanitized `info.toml`) are not explicitly documented or machine-verifiable.

    Fix: Create SECURITY.md documenting trusted vs. untrusted input sources, bounds on filesystem operations, and agent operation limits (e.g., 'reset/init only within rustlings/ directory'). Reference it in README.

  15. mediumAgent Safety

    No CODEOWNERS file for security-critical paths

    Lack of CODEOWNERS means changes to src/cmd.rs (command execution), src/init.rs (filesystem init), and src/embedded.rs (embedded file injection) have no review gate.

    Fix: Add CODEOWNERS file with strict review requirement for src/cmd.rs, src/init.rs, src/embedded.rs, and rustlings-macros/.

  16. lowMachine Orientation

    Exercise metadata format is not documented near the exercises themselves

    rustlings-macros/info.toml defines the exercise schema (name, dir, hint, test flag) and welcome/final messages, but there is no README in rustlings-macros/ explaining the schema or pointing agents to this file. The CONTRIBUTING.md mentions the schema, but only in the 'Adding An Exercise' section (not the main README).

    Fix: Add a brief rustlings-macros/README.md documenting the info.toml format, or add a comment block at the top of info.toml itself explaining the format and pointing to CONTRIBUTING.md. This aids navigation.

  17. lowCode Navigability

    Context-window risk: app_state.rs at 430+ LOC with interconnected methods

    While not extremely large, app_state.rs combines state mutations, file I/O, exercise lifecycle, and editor coordination in one struct. A method like check_all_exercises() (line ~150+) spans 100+ LOC across multiple helper calls, making it hard to trace side effects in a single LLM context window.

    Fix: Consider extracting state persistence logic (write(), read()) into a separate StateFile wrapper struct, and exercise checking logic into a separate CheckRunner struct. This creates clearer module boundaries and reduces method complexity per file.

  18. lowCode Navigability

    Const generic FORCE_STRICT_CLIPPY not obviously a compile-time decision

    exercise.rs:run() uses const generic FORCE_STRICT_CLIPPY to control behavior, but call sites don't make it clear this is a compile-time choice and not a runtime branch. An agent may misinterpret as a runtime flag or miss that there are two compiled code paths.

    Fix: Replace with two explicit method names (run_exercise, run_solution) or add a detailed doc comment on the const parameter explaining it forces two separate compiled implementations and why.

  19. lowVerification Surface

    No explicit type-check step in CI

    Type checking is implicit in cargo build/test and not surfaced separately. An agent must infer type safety only by observing build success, not by reading an explicit `cargo check` step.

    Fix: Add a CI job that runs 'cargo check --all-targets' before clippy and test, making type checking machine-readable as a separate gate.

  20. mediumContext Economy

    README redirects to external website, minimal local orientation

    The README.md is only 7 lines and points entirely to rustlings.rust-lang.org, providing no local build/navigation guidance. An agent cannot infer from the README alone whether to compile the CLI, run exercises interactively, or examine the macro system.

    Fix: Expand README.md to include: (1) brief description of rustlings as an exercise framework + CLI tool; (2) link to CONTRIBUTING.md for development; (3) note that exercises/ and solutions/ are embedded via macro and auto-generated; (4) pointer to rustlings-macros/ for architecture.

  21. lowContext Economy

    No explicit linguist vendoring markers for embedded macro output

    The macro system in rustlings-macros/ generates or embeds file content, but there is no .gitattributes with `linguist-generated` or similar to signal to agents (and GitHub) that the exercises/ and solutions/ directories are largely derived, not hand-authored core logic.

    Fix: Add .gitattributes file with entries like `exercises/ linguist-generated` and `solutions/ linguist-generated` to reduce perceived codebase size and signal that these are build artifacts, not primary sources.

Show your score

Latch badge
[![Latch score](https://latch.fyi/api/badge/8100fe47-809f-4b26-ab86-65052718ebd3)](https://latch.fyi/rust-lang/rustlings)

Share this analysis

https://latch.fyi/rust-lang/rustlings

Fixed some issues? Re-analyze to measure your progress →

Copy the whole report

Grab the entire verdict in one go — a Markdown block for a README or an issue, plain text, or a prompt you can paste straight into an LLM.

Was this verdict fair?

One tap helps — or tell us more.