# How to Check All Rustlings Exercises at Once: Complete Guide

> Master Rustlings with our guide on how to check all Rustlings exercises at once. Run rustlings check to compile and test exercises in parallel with a real-time progress bar.

- Repository: [The Rust Programming Language/rustlings](https://github.com/rust-lang/rustlings)
- Tags: how-to-guide
- Published: 2026-03-05

---

**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:

```bash
rustlings check

```

This command initiates a comprehensive validation process that:

1. Loads your current progress from [`.rustlings_state.json`](https://github.com/rust-lang/rustlings/blob/main/.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`](https://github.com/rust-lang/rustlings/blob/main/src/main.rs)

The entry point for the command resides in [`src/main.rs`](https://github.com/rust-lang/rustlings/blob/main/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)`:

```rust
// 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`](https://github.com/rust-lang/rustlings/blob/main/src/app_state.rs)

The core logic lives in [`src/app_state.rs`](https://github.com/rust-lang/rustlings/blob/main/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:

```rust
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`](https://github.com/rust-lang/rustlings/blob/main/src/watch/state.rs)

While workers process exercises, the main thread receives status updates and feeds them to `CheckProgressVisualizer` in [`src/watch/state.rs`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/.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:

```rust
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`](https://github.com/rust-lang/rustlings/blob/main/src/app_state.rs).
- **Real-time progress** displays through `CheckProgressVisualizer` in [`src/watch/state.rs`](https://github.com/rust-lang/rustlings/blob/main/src/watch/state.rs).
- **State persistence** automatically updates [`.rustlings_state.json`](https://github.com/rust-lang/rustlings/blob/main/.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`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/.rustlings_state.json) in your working directory. The `AppState::write()` method in [`src/app_state.rs`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/Cargo.toml) and using the `InfoFile` parser to load exercise definitions, as demonstrated in the programmatic usage example above.