How to Check All Rustlings Exercises at Once: Complete Guide

Run rustlings check in your terminal to verify every exercise in the course, which compiles and tests each file in parallel while displaying a real-time progress bar.

The rustlings CLI tool from the rust-lang/rustlings repository provides a built-in command to validate your progress through the entire Rust curriculum. When you check all Rustlings exercises at once, the tool automatically marks completed items, identifies the first pending exercise, and persists your state for future sessions.

Using the rustlings check Command

To verify every exercise in your Rustlings directory, execute the following in your terminal:

rustlings check

This command initiates a comprehensive validation process that:

  1. Loads your current progress from .rustlings_state.json
  2. Spawns a worker thread pool matching your CPU core count
  3. Compiles and runs tests for each exercise concurrently
  4. Displays a dynamic progress bar showing completion percentage
  5. Updates your state file with newly completed exercises
  6. Reports the first pending exercise if any remain incomplete

How the Check All Feature Works Internally

The check all functionality spans multiple source files, coordinating parallel execution with terminal visualization.

CLI Parsing in src/main.rs

The entry point for the command resides in src/main.rs, where the CheckAll subcommand is defined. When you invoke rustlings check, the program matches the CheckAll arm and calls app_state.check_all_exercises(&mut stdout):

// From src/main.rs lines 49-56
match &args.command {
    Some(Commands::CheckAll) => {
        if let Some(pending) = app_state.check_all_exercises(&mut stdout)? {
            // Handle pending exercise output
        }
    }
    // ... other commands
}

Parallel Execution in src/app_state.rs

The core logic lives in src/app_state.rs. The check_all_exercises method (lines 105-113) temporarily hides the terminal cursor, delegates to check_all_exercises_impl, then restores the cursor:

pub fn check_all_exercises(&mut self, stdout: &mut StdoutLock) -> Result<Option<usize>> {
    // Cursor management for clean UI
    self.check_all_exercises_impl(stdout)
}

The check_all_exercises_impl function (lines 14-45) creates a thread pool sized to your available CPU cores. Each worker thread pulls the next exercise index from an atomic counter, executes exercise.run_exercise, and transmits progress updates through a channel:

  • Checking → Exercise is being compiled/tested
  • Done → Exercise passed and is marked complete
  • Pending → Exercise failed or is incomplete

Progress Visualization in src/watch/state.rs

While workers process exercises, the main thread receives status updates and feeds them to CheckProgressVisualizer in src/watch/state.rs (lines 272-306). This component renders a dynamic progress bar in your terminal:


[##########--------------] 45% (9/20) checking...

The visualizer updates in real-time as each thread completes its assigned exercise, providing immediate feedback on the validation process.

Result Aggregation and State Persistence

After all workers finish, check_all_exercises_impl iterates over collected statuses (lines 67-99):

  • Done: Marks the exercise as completed in AppState
  • Pending: Records the first pending index to return to the user
  • Errors: If a thread encounters resource limits (e.g., too many open files), the function falls back to sequential execution for the problematic exercise

Finally, the updated AppState persists to .rustlings_state.json via self.write() (lines 101-103), ensuring your progress is saved for future sessions.

Programmatically Checking All Exercises

You can also invoke the check functionality from your own Rust code by linking to the rustlings library:

use rustlings::{AppState, InfoFile};
use std::io::{self, StdoutLock};

fn run_check() -> anyhow::Result<()> {
    // Load exercise definitions from info.toml
    let info = rustlings::InfoFile::parse()?;
    let (mut app_state, _) = rustlings::AppState::new(
        info.exercises,
        info.final_message.unwrap_or_default(),
    )?;

    // Execute the check routine
    let mut stdout = io::stdout().lock();
    if let Some(first_pending) = app_state.check_all_exercises(&mut stdout)? {
        println!("First pending exercise index: {}", first_pending);
    } else {
        println!("All exercises are solved!");
    }
    Ok(())
}

This approach leverages the same parallel checking infrastructure used by the CLI, including the CheckProgressVisualizer for real-time feedback.

Summary

  • Run rustlings check to validate every exercise in the course simultaneously.
  • The command utilizes parallel execution across all CPU cores via check_all_exercises_impl in src/app_state.rs.
  • Real-time progress displays through CheckProgressVisualizer in src/watch/state.rs.
  • State persistence automatically updates .rustlings_state.json with completed exercises.
  • Programmatic access allows custom scripts to invoke the same validation logic through the AppState API.

Frequently Asked Questions

What is the difference between rustlings check and rustlings watch?

rustlings check runs every exercise once in parallel and exits, providing a snapshot of your overall progress. rustlings watch monitors files continuously, re-running exercises as you save changes, and is designed for active development on individual exercises.

How does Rustlings check exercises in parallel?

The check_all_exercises_impl function in src/app_state.rs spawns a thread pool matching your CPU core count. Each worker thread pulls the next exercise index from an atomic counter, executes exercise.run_exercise, and reports status through a channel. If resource limits are hit, it falls back to sequential execution for that specific exercise.

Where does Rustlings store my exercise progress?

Progress persists to .rustlings_state.json in your working directory. The AppState::write() method in src/app_state.rs serializes completed exercises to this file after each check operation, allowing you to resume progress across sessions.

Can I check all Rustlings exercises without installing the CLI?

Yes, you can import the rustlings crate as a library and invoke AppState::check_all_exercises() programmatically. This requires adding the rustlings dependency to your Cargo.toml and using the InfoFile parser to load exercise definitions, as demonstrated in the programmatic usage example above.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →