← thecodex.expert · The Codex Family of Knowledge

Free · No account · Official sources only

Rust — Cradle to Mastery

A complete, structured path through Rust — from your first line to writing memory-safe, concurrent systems software with no garbage collector. Every lesson points at reference pages already written and verified on this site. Free, no account, no sign-up.

30 lessons 6 stages ~33 hours of reading 10 projects Rust 2021 edition, stable channel · curriculum current as of 2026
Start Lesson 1 → Browse the reference instead

How this course works

1
Follow the stages in orderEach stage assumes the one before it. Stage 2 in particular assumes Stage 1 cold.
2
Read the tab the lesson namesReference pages have Beginner, Intermediate and Expert tabs. Read only what the lesson asks for on a first pass.
3
Run every exampleKeep the playground open in a second tab. Reading code you have not run is how misunderstandings survive.
4
Build after each stageDo not save all ten projects for the end. Pick one up as soon as a stage gives you enough to attempt it.
Casual pace: ~10 weeks at 4 hours a week
Steady pace: ~5 weeks at 8 hours a week
Intensive: ~2 weeks full-time
STAGE 0

Before You Start

Understand what problem Rust actually solves before writing a line of code. These two lessons take about an hour and explain why the rest of this course looks the way it does.

LESSON 1

What is Rust?

Origin at Mozilla, and the memory-safety problem it was built to solve

Rust was created by Graydon Hoare at Mozilla Research and reached 1.0 in 2015, aimed squarely at a problem C and C++ never solved: memory safety without a garbage collector. Understanding that goal explains the borrow checker before you ever meet it — it is not an obstacle bolted onto the language, it is the language.

📚 🟩 Read the Beginner tab only.
Key focus: Why Rust trades a steeper learning curve for compile-time memory and thread safety, with zero runtime cost.
⏱ 30 min
Required Reading
→
What is Rust? — The Codex

Rust's origin story, the memory-safety guarantees it makes, where it runs in production, and how it compares to C++ and Go.

LESSON 2

Setting Up Rust

Installing rustup, Cargo, and running your first program

rustup installs and manages the Rust toolchain, and Cargo — Rust's build tool and package manager — is used for nearly everything from the first day. Getting both installed correctly, plus rust-analyzer in your editor, is this lesson's entire job.

📚 🟩 Read the Beginner tab only.
Key focus: Get `cargo new` and `cargo run` working, and confirm your editor shows borrow-checker errors as you type.
⏱ 30 min
Required Reading
→
Setting Up Rust — The Codex

Installing Rust via rustup, the toolchain layout, cargo new/run/build, and editor setup with rust-analyzer.

STAGE 1

Language Fundamentals

The core syntax and built-in types you will use in every Rust program. Six lessons — do not rush string handling, since it is where Rust's rules first feel different from other languages.

LESSON 3

Variables & Mutability

Immutable by default, and the mut keyword

Every Rust variable is immutable unless you explicitly write `mut`. This is not a style preference — it is the first piece of a language-wide bias toward making mutation visible, which the borrow checker later builds on.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Why immutable-by-default exists, and the difference between mut and a shadowed rebinding.
⏱ 45 min
Required Reading
→
Variables & Mutability — The Codex

let vs let mut, shadowing, constants, and Rust's static, strongly-typed, inferred type system.

LESSON 4

Data Types

Scalars, compound types, and Rust's fixed-width integers

Rust's integers have explicit widths (i32, u64, and so on) and the compiler will not silently convert between them. Combined with tuples and fixed-size arrays, this lesson covers the building blocks every later type is made from.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Explicit integer widths, and why Rust refuses implicit numeric conversion.
⏱ 1 hours
Required Reading
→
Data Types — The Codex

Integer and float types, booleans, chars, tuples, arrays, and type inference and annotation.

LESSON 5

Control Flow

if as an expression, loop, while, for, and labeled breaks

if is an expression in Rust, so it can produce a value directly into a let binding — no ternary operator needed. `loop` is an intentional infinite loop that can also return a value via break, which for and while cannot.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: if as an expression, and the three loop forms with labeled break/continue.
⏱ 1 hours
Required Reading
→
Control Flow — The Codex

if/else as expressions, loop/while/for, break with a value, and loop labels for nested loops.

LESSON 6

String Handling

String vs &str, and why you can't index a string by position

Rust guarantees every String and &str is valid UTF-8, which is exactly why `s[0]` does not compile — a byte index could land in the middle of a multi-byte character. This lesson is where Rust's rules first feel stricter than most languages, for a genuine safety reason.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: The owned String vs the borrowed &str slice, and iterating by chars vs bytes.
⏱ 1 hours
Required Reading
→
String Handling — The Codex

String vs &str, UTF-8 guarantees, concatenation, slicing by byte range, and the chars()/bytes() iterators.

LESSON 7

Structs

Grouping related data, and the three struct forms

Structs are how Rust models data, in the same role classes play elsewhere but with no inheritance. This lesson covers named-field, tuple, and unit structs, plus the impl block where methods are attached separately from the data.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: The three struct forms, and why methods live in a separate impl block rather than inside the struct.
⏱ 1 hours
Required Reading
→
Structs — The Codex

Named-field, tuple, and unit structs, the impl block, associated functions vs methods, and the Debug trait.

LESSON 8

Enums & Pattern Matching

Algebraic data types, and match's exhaustiveness check

Rust enums can carry different data per variant — Option<T> and Result<T, E> are both ordinary enums defined this way. `match` forces you to handle every variant, which is how Rust eliminates an entire category of null-reference and unhandled-case bugs at compile time.

📚 🟩 Beginner → ⚡ Intermediate → 🔥 Expert.
Key focus: Enums as algebraic data types, and why the compiler rejects a non-exhaustive match.
⏱ 1.25 hours
Required Reading
→
Enums & Pattern Matching — The Codex

Enum definitions with data-carrying variants, match and if let, exhaustiveness checking, and Option<T>.

STAGE 2

Ownership — Rust's Defining Feature

This is why Rust exists. Ownership, borrowing and lifetimes are enforced entirely at compile time and are what let Rust guarantee memory safety with no garbage collector. Take these five lessons slowly — nothing later in the language makes sense without them.

LESSON 9

Ownership & Borrowing

One owner per value, and borrowing instead of copying

Every value in Rust has exactly one owner, and when that owner goes out of scope the value is dropped automatically — no garbage collector, no manual free, no double-free. Borrowing lets code use a value without taking ownership of it, and this single rule is the foundation everything else in this stage builds on.

📚 🟩 Beginner → ⚡ Intermediate → 🔥 Expert.
Key focus: Move semantics for non-Copy types, and the rule of one mutable OR many immutable borrows at a time.
⏱ 2 hours
Required Reading
→
Ownership & Borrowing — The Codex

Ownership rules, move vs copy, the Drop trait, borrowing with & and &mut, and the aliasing rules the compiler enforces.

LESSON 10

References & Slices

Borrowed views into data, without copying it

A reference lets a function read or modify data it does not own, and a slice is a reference to a contiguous run of a collection — a string slice or an array slice — without owning or copying the underlying data.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Why a function taking &str accepts both a String and a string literal, and how slices avoid copying.
⏱ 1.25 hours
Required Reading
→
References & Slices — The Codex

Reference syntax, dereferencing, string slices and array slices, and slices as function parameters.

LESSON 11

Lifetimes

Compiler-checked proof that references don't outlive their data

A lifetime is not a runtime concept — it is the compiler's proof, checked entirely at compile time, that a reference never outlives the data it points to. Most of the time lifetimes are inferred silently; this lesson is about the cases where you must name them explicitly.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: Reading 'a lifetime annotations, and the three elision rules that make most functions need none.
⏱ 1.25 hours
Required Reading
→
Lifetimes — The Codex

Lifetime annotation syntax, lifetime elision rules, lifetimes in structs, and the 'static lifetime.

LESSON 12

The Borrow Checker, Deep Dive

Why it rejects code, and how to work with it

The borrow checker is the compiler pass that enforces ownership and borrowing rules, and its errors are usually pointing at a real bug in your reasoning, not an arbitrary restriction. This lesson works through the classic rejected patterns and the idiomatic ways to restructure code so they compile.

📚 🔥 Expert.
Key focus: Reading a borrow-checker error to find the real design problem, instead of fighting the compiler.
⏱ 1.25 hours
Required Reading
→
The Borrow Checker, Deep Dive — The Codex

Common borrow-checker rejections, non-lexical lifetimes, splitting borrows, and interior mutability as an escape hatch.

LESSON 13

Smart Pointers

Box, Rc, and RefCell — managing heap data without a GC

Ordinary references cover most cases, but some data needs to live on the heap (Box), be shared by multiple owners (Rc), or be mutated through a shared reference (RefCell). These smart pointer types are how Rust handles the remaining cases ownership alone cannot express.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: When Box, Rc, and RefCell are each the right tool, and RefCell's runtime-checked interior mutability.
⏱ 1.25 hours
Required Reading
→
Smart Pointers — The Codex

Box<T> for heap allocation, Rc<T> for shared ownership, RefCell<T> and interior mutability, and the Deref/Drop traits.

STAGE 3

Generics, Traits & Collections

Rust replaces inheritance with traits and generics, and ships a small but sharp set of collection types. Six lessons, ending with closures and iterators — the two features that make idiomatic Rust read more like a functional language than a systems one.

LESSON 14

Generics

Type parameters, checked at compile time with zero runtime cost

Generics let one function or struct work over many types, and because Rust monomorphizes generics — generating a specialized copy per concrete type at compile time — there is no runtime overhead at all, unlike generics in many other languages.

📚 ⚡ Intermediate.
Key focus: Type parameter syntax, and how monomorphization gives generics zero runtime cost.
⏱ 1 hours
Required Reading
→
Generics — The Codex

Generic functions, structs and enums, trait bounds on type parameters, and monomorphization.

LESSON 15

Traits & Trait Objects

Shared behavior, and dyn Trait's runtime dispatch

A trait defines behavior a type can implement, similar to an interface, and trait bounds let generic code require that behavior at compile time. `dyn Trait` is the other option — trading that compile-time speed for the runtime flexibility of storing different types behind one pointer.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: Static dispatch via trait bounds vs dynamic dispatch via dyn Trait, and when each is the right call.
⏱ 1.25 hours
Required Reading
→
Traits & Trait Objects — The Codex

Defining and implementing traits, default methods, trait bounds, impl Trait, and dyn Trait / trait objects.

LESSON 16

Types & Traits, Tied Together

How structs, enums, traits and generics compose into one system

You have now met structs, enums, generics and traits separately. This lesson is the synthesis — seeing how they combine into Rust's actual answer to object-oriented design, without classes or inheritance anywhere in the picture.

📚 ⚡ Intermediate.
Key focus: Seeing the pieces you already learned work together in one realistic type design.
⏱ 1 hours
Required Reading
→
Types & Traits, Tied Together — The Codex

How structs, enums, impl blocks, pattern matching, Option, traits, generics and dyn Trait fit into one coherent model.

LESSON 17

Collections

Vec, HashMap, HashSet, and when to reach for each

Rust's standard collections cover most real programs: Vec<T> for growable lists, HashMap<K, V> for lookups, and HashSet<T> for uniqueness. Each interacts with ownership in a specific way worth seeing before you use them in real code.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Choosing between Vec, HashMap and HashSet, and how ownership rules apply when you insert into them.
⏱ 1 hours
Required Reading
→
Collections — The Codex

Vec<T> operations, HashMap<K, V> and the entry API, HashSet<T>, and iterating collections without taking ownership.

LESSON 18

Closures

Functions that capture their environment, and the three Fn traits

A closure can capture variables from its surroundings, and Rust expresses exactly how — by reference, by mutable reference, or by move — through the Fn, FnMut and FnOnce traits. Getting this straight explains a class of closure-related compiler errors.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: The difference between Fn, FnMut and FnOnce, and when move is required.
⏱ 1 hours
Required Reading
→
Closures — The Codex

Closure syntax, capturing by reference vs by move, the Fn/FnMut/FnOnce traits, and closures as function parameters.

LESSON 19

Iterators

Lazy, zero-cost chains — map, filter, and collect

Iterator chains in Rust compile down to the same machine code as a hand-written loop — a textbook zero-cost abstraction. This lesson covers the Iterator trait itself and the adapters (map, filter, fold) you will reach for constantly in idiomatic Rust.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: Why iterator chains are lazy until consumed, and how collect() decides what to build.
⏱ 1.25 hours
Required Reading
→
Iterators — The Codex

The Iterator trait, common adapters (map, filter, fold, zip), laziness, and implementing Iterator for your own type.

STAGE 4

Error Handling & Concurrency

Rust has no exceptions and no garbage-collected runtime backstopping thread safety — both are handled at compile time instead. Five lessons covering Result, threads, async, and the boundary where you can deliberately step outside the compiler's guarantees.

LESSON 20

The Result Type

Result<T, E>, and how ? turns error propagation into one character

Result<T, E> replaces exceptions: a function that can fail returns Result instead of throwing. The ? operator then propagates an Err straight out of the current function, turning what would be several lines of error-checking into a single character at the call site.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Reading and writing ?-based error propagation, and Result vs Option's different purposes.
⏱ 1.25 hours
Required Reading
→
The Result Type — The Codex

Result<T, E> and Option<T>, the ? operator, combinators like map/and_then, and unwrap vs proper handling.

LESSON 21

Concurrency & Threads

std::thread, message passing, and Send/Sync enforced by the compiler

Rust's marketing calls this "fearless concurrency" for a specific reason: the Send and Sync traits let the compiler reject a data race before the program ever runs, rather than catching it at runtime or not at all. This lesson covers spawning threads, message passing, and shared state.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: How Send and Sync let the compiler catch data races at compile time.
⏱ 1.5 hours
Required Reading
→
Concurrency & Threads — The Codex

std::thread::spawn, message passing with mpsc channels, Arc<Mutex<T>> for shared state, and the Send/Sync marker traits.

LESSON 22

Async/Await

Futures, .await, and why Rust needs a runtime like Tokio

Rust's async functions return a Future that does nothing until polled — unlike JavaScript's promises, which start running immediately. That laziness is why async Rust needs an executor such as Tokio to actually drive futures to completion.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: Why a Rust future is inert until polled, and what a runtime like Tokio actually does.
⏱ 1.5 hours
Required Reading
→
Async/Await — The Codex

async fn and .await, the Future trait, why an executor is required, and async vs threads for I/O-bound work.

LESSON 23

Error Handling & Concurrency, Tied Together

Result, ?, panic, threads and channels in one realistic program

This lesson is the synthesis for this stage: propagating a Result with ? through a function that also spawns threads and shares state behind Arc<Mutex<T>>, plus the panic/threading interaction — what happens to the rest of a program when one thread panics.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: Combining ?-based error propagation with threads, channels and shared state in one piece of code.
⏱ 1.25 hours
Required Reading
→
Error Handling & Concurrency, Tied Together — The Codex

Custom error types, panic vs Result, propagating errors across thread boundaries, and Arc/Mutex/mpsc in combination.

LESSON 24

Unsafe Rust

The five things unsafe unlocks, and the safety contract you take on

`unsafe` does not turn off the borrow checker; it unlocks exactly five capabilities the compiler cannot otherwise verify, such as dereferencing a raw pointer. Every unsafe block is a promise from you to the compiler, and idiomatic Rust wraps unsafe code in a safe API almost immediately.

📚 🔥 Expert.
Key focus: The exact five capabilities unsafe unlocks, and why they should be wrapped in a safe API right away.
⏱ 1 hours
Required Reading
→
Unsafe Rust — The Codex

Raw pointers, calling unsafe functions, mutable statics, unsafe traits, union fields, and safe abstractions over unsafe code.

STAGE 5

Tooling, Performance & Shipping

Cargo, testing and the standard library are what turn correct Rust into a shippable project. Six lessons on organizing, testing, and understanding the performance model underneath it all.

LESSON 25

Performance & Memory

Zero-cost abstractions, and matching hand-written C

Rust's high-level features — iterators, generics, closures — are designed to compile away entirely, so idiomatic Rust routinely matches hand-written C performance. This lesson is about why that promise holds, and the stack/heap model underneath it.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: What "zero-cost abstraction" actually means at the compiled-code level.
⏱ 1 hours
Required Reading
→
Performance & Memory — The Codex

Stack vs heap allocation, zero-cost abstractions, monomorphization's role in performance, and profiling basics.

LESSON 26

Macros

Code that writes code — vec! and println! are macros, not functions

Rust macros run at compile time and can generate code, which is why vec![] can take any number of arguments when ordinary functions cannot. This lesson covers declarative macros (macro_rules!) and gives you enough to recognize derive macros like #[derive(Debug)] for what they are.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: Why vec! and println! need to be macros, and the basics of macro_rules!.
⏱ 1 hours
Required Reading
→
Macros — The Codex

Declarative macros with macro_rules!, derive macros, attribute macros, and when a macro is the right tool over a function.

LESSON 27

Modules & Crates

Organizing code, and Rust's privacy-by-default rule

Rust items are private to their module by default; you opt in to visibility with `pub`, which is the inverse of many languages' public-by-default habit. This lesson covers the mod/use system and how a project is split across multiple files.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Privacy-by-default, and how mod and use organize a multi-file project.
⏱ 1 hours
Required Reading
→
Modules & Crates — The Codex

Module declarations, the pub keyword, use and re-exports, and splitting a crate across multiple files.

LESSON 28

Cargo & Packages

Cargo.toml, crates.io, and semantic versioning

Cargo builds, tests, documents and publishes Rust code, and Cargo.lock gives every build reproducible dependency versions. This lesson covers adding dependencies from crates.io, workspaces, and Cargo's command surface beyond build and run.

📚 ⚡ Intermediate.
Key focus: Reading and editing Cargo.toml, and what Cargo.lock guarantees.
⏱ 1 hours
Required Reading
→
Cargo & Packages — The Codex

Cargo.toml and Cargo.lock, adding dependencies, semantic versioning, workspaces, and cargo's built-in commands.

LESSON 29

The Standard Library Tour

std — collections, IO, the filesystem, and environment access

Rust's std is deliberately smaller than Go's or Python's, pushing things like async runtimes and random number generation out to crates.io. This lesson maps what actually lives in std, so you know when to reach for it before adding a dependency.

📚 ⚡ Intermediate.
Key focus: Which jobs std covers directly, and which common needs deliberately live in external crates instead.
⏱ 1 hours
Required Reading
→
The Standard Library Tour — The Codex

std::collections, std::io and std::fs, std::env, std::process, and what std intentionally leaves out.

LESSON 30

Testing

#[test], integration tests, and cargo test

Testing ships with Cargo — no separate framework required for the basics. This lesson covers unit tests in the same file as the code, integration tests in a separate tests/ directory, and the assert! family of macros that make a failing test point straight at the problem.

📚 🟩 Beginner → ⚡ Intermediate → 🔥 Expert.
Key focus: Where unit tests vs integration tests live, and reading a cargo test failure.
⏱ 1.25 hours
Required Reading
→
Testing — The Codex

#[test] and #[cfg(test)], assert!/assert_eq!/assert_ne!, integration tests in tests/, and cargo test's output.

STAGE 6

Concepts That Cross Languages

These pages explain ideas that are not specific to Rust — they apply to every language you will ever learn. Read them once and the next language costs you far less effort. They pair well with the lessons above rather than replacing them.

STAGE 7

Build Real Things — 10 Projects

Reading is not enough. These 10 projects — five basic, five medium — are chosen because each one exercises something specific you learned above, and because they are genuinely idiomatic Rust rather than generic exercises. Each link below opens the project brief; the Rust implementation walkthrough is in progress.

BASIC — 5 PROJECTS
→
Number Guessing Game

Loops, stdin input, and the rand crate.

→
Temperature Converter

Functions, floating-point types, and match expressions.

→
Word Counter

File reading, HashMap for counting, and the String/&str split.

→
To-Do List (CLI)

Structs, Vec<T>, and persisting state to a file.

→
Password Generator

The rand crate, char handling, and building a String.

MEDIUM — 5 PROJECTS
→
Web Scraper

HTTP requests, Result-based error propagation with ?, and regex extraction.

→
REST API

An async web framework, JSON via serde, and shared state behind Arc<Mutex<T>>.

→
CLI Task Manager

Argument parsing, structs, and file persistence.

→
URL Shortener

An HTTP service with storage — a complete small system.

→
Log Analyser

Streaming large files with BufReader, and a HashMap-based counter.

STAGE 8

Practice & Experimentation

Ongoing, not a final step. Use these throughout the course — try every snippet you read, and run anything you are unsure about rather than assuming.

Resources
→
Rust Playground

Run Rust code without installing anything, via the Rust Playground.

→
Rust Snippets

Copy-ready idiomatic patterns to keep beside you while you build.

→
Rust Reference Hub

All 30 topic pages in one index, for looking things up later.