# How Rustlings Exercises Are Structured: Name, Path, and Test Mode Explained

> Understand Rustlings exercise structure Learn how name path and test mode are defined in info toml for efficient Rust learning

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

---

**Rustlings exercises are structured as data-driven records defined in an embedded [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) file, where each entry specifies a name, computed file path, boolean test flag, and execution mode that determines whether `cargo test` or simple compilation is required.**

The `rust-lang/rustlings` repository uses this declarative approach to manage over 100 exercises without hard-coding paths or metadata in the runner logic. Instead, the application parses the TOML configuration at runtime to build `Exercise` objects that know how to validate themselves.

## The Core Data Model

Rustlings represents exercise metadata through a three-layer architecture that transforms raw TOML into executable units.

The `InfoFile` struct (defined in [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs)) acts as the top-level container. It deserializes the TOML array of `[[exercises]]` entries into a vector of `ExerciseInfo` structs. Each `ExerciseInfo` contains the raw attributes: `name`, optional `dir`, `test` boolean, `hint`, and `strict_clippy` flag.

The `Exercise` struct (defined in [`src/exercise.rs`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs)) is the runtime representation. It consumes an `ExerciseInfo` and computes the final file path, determines the execution mode, and implements the `RunnableExercise` trait that handles the actual `cargo` invocation logic.

## How Exercise Attributes Are Derived

### Name

The **name** attribute is the canonical identifier for the exercise, stored directly in the TOML entry. According to the source code in [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs), the `name` field is a required string that typically matches the file stem (e.g., `variables1`). This value is used for display purposes in the UI and for matching user input when running specific exercises.

### Path

The **path** is computed dynamically rather than stored explicitly. In [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs), the `ExerciseInfo::path()` method (lines 33-53) constructs the relative path using this logic:

```rust
// Pseudocode based on src/info_file.rs lines 33-53
if let Some(dir) = &self.dir {
    format!("exercises/{}/{}.rs", dir, self.name)
} else {
    format!("exercises/{}.rs", self.name)
}

```

This ensures all exercise paths start with the `exercises/` directory prefix. If the TOML entry includes a `dir` field (e.g., `dir = "01_variables"`), the file is nested within that subdirectory.

### Test Flag

The **test** boolean determines whether the exercise requires test validation. In [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs), the `ExerciseInfo` struct defines this field with a `default_true` attribute, meaning exercises default to `test = true` unless explicitly set to `false`.

When `test` is `true`, the runner executes `cargo test` to verify the solution. When `false`, the exercise is "compile-only" — the runner only checks that the code compiles successfully without running tests.

### Execution Mode

The **mode** is not a separate TOML field but a runtime property derived from the `test` flag. In [`src/exercise.rs`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs), the `Exercise` struct exposes this through the `RunnableExercise` trait implementation. The `run()` method (lines 24-57) branches based on the `test` field:

- **Test mode**: Constructs a `cargo test` command, runs tests, then executes the binary if tests pass.
- **Run-only mode**: Skips testing and only compiles and runs the binary.

## Source Code Architecture

The exercise structure is implemented across four key files in the repository:

| File | Purpose |
|------|---------|
| [`rustlings-macros/info.toml`](https://github.com/rust-lang/rustlings/blob/main/rustlings-macros/info.toml) | The embedded TOML file containing all official exercise definitions |
| [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs) | Parses TOML into `InfoFile` and `ExerciseInfo` structs; handles path computation |
| [`src/exercise.rs`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs) | Defines the `Exercise` struct and `RunnableExercise` trait for execution logic |
| [`src/main.rs`](https://github.com/rust-lang/rustlings/blob/main/src/main.rs) | Entry point that loads exercises and drives the interactive UI |

## Step-by-Step Exercise Initialization

When you launch Rustlings, the program transforms the static TOML configuration into executable objects through this pipeline:

1. **Load the TOML** — `InfoFile::parse()` (lines 92-124 in [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs)) reads the embedded [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) and deserializes it into a vector of `ExerciseInfo` structs.

2. **Compute paths** — For each `ExerciseInfo`, the program calls `ExerciseInfo::path()` (lines 33-53) to generate the relative file path, checking whether a `dir` field is present to determine subdirectory nesting.

3. **Build Exercise objects** — The `Exercise` struct (defined at lines 67-78 in [`src/exercise.rs`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs)) is instantiated with the computed path, name, test flag, and other metadata.

4. **Determine execution mode** — The boolean `test` field is evaluated to set the execution mode. If `true`, the runner prepares to invoke `cargo test`; if `false`, it prepares for compile-only validation.

5. **Run validation** — The UI calls `exercise.run_exercise()` or `exercise.run_solution()`, which delegates to `RunnableExercise::run()` (lines 24-57) to execute the appropriate cargo commands.

## Practical Example

Consider the `variables1` exercise defined in [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml):

```toml
[[exercises]]
name = "variables1"
dir = "01_variables"
test = false
hint = "..."

```

**Name**: `variables1` (directly from the `name` field).

**Path**: [`exercises/01_variables/variables1.rs`](https://github.com/rust-lang/rustlings/blob/main/exercises/01_variables/variables1.rs) (computed by `ExerciseInfo::path()` because `dir` is present).

**Test**: `false` (explicitly set, overriding the default `true`).

**Mode**: Run-only mode. When you run this exercise, Rustlings skips `cargo test` and only verifies that the code compiles and runs successfully.

## Summary

- Rustlings exercises are defined declaratively in an embedded [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) file, parsed by `InfoFile::parse()` in [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs).
- The **name** is the canonical identifier read directly from TOML.
- The **path** is computed dynamically by `ExerciseInfo::path()`, always prefixed with `exercises/` and optionally nested in subdirectories via the `dir` field.
- The **test** flag defaults to `true` but can be overridden; it determines whether `cargo test` is invoked.
- The **mode** is a runtime property derived from the `test` flag, implemented in [`src/exercise.rs`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs) through the `RunnableExercise` trait.

## Frequently Asked Questions

### How does Rustlings determine the file path for an exercise?

Rustlings computes the path dynamically in [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs) via the `ExerciseInfo::path()` method. If the TOML entry includes a `dir` field, the path becomes `exercises/<dir>/<name>.rs`; otherwise it is `exercises/<name>.rs`. This ensures all exercises reside under the `exercises/` directory prefix.

### What is the difference between test mode and run-only mode in Rustlings?

Test mode exercises have `test = true` (the default) and require `cargo test` to pass before the binary runs. Run-only mode exercises have `test = false`, meaning the runner only checks that the code compiles successfully without executing any tests. This distinction is handled in [`src/exercise.rs`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs) by the `RunnableExercise::run()` implementation.

### Can I override the default exercise configuration in Rustlings?

Yes. While Rustlings embeds the official [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) in [`rustlings-macros/info.toml`](https://github.com/rust-lang/rustlings/blob/main/rustlings-macros/info.toml), you can supply a local [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) file. The `InfoFile::parse()` method in [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs) will read your local configuration instead, allowing you to define custom exercises with your own names, paths, test flags, and directory structures.

### Where is the exercise metadata stored in the Rustlings source code?

The canonical exercise metadata resides in [`rustlings-macros/info.toml`](https://github.com/rust-lang/rustlings/blob/main/rustlings-macros/info.toml) as an embedded TOML file. At runtime, [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs) parses this data into `ExerciseInfo` structs, and [`src/exercise.rs`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs) transforms these into runnable `Exercise` objects that the UI in [`src/main.rs`](https://github.com/rust-lang/rustlings/blob/main/src/main.rs) consumes.