Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path →
- Reference
- 58 lessons
The course on one page
Every piece of Rust the course introduces, chapter by chapter, with a real line from the lesson that teaches it. A reminder, not a replacement: each row links to its lesson.
Chapter 1: Hello
At the end of it, Chatterbox prints a banner and says hello.
- 1.1 What a program is
- Say what a program is in one sentence
- 1.2 Make and run a project
- Create a Rust project with cargo new
- 1.3 Printing and comments
- Print text with println! and fill holes with {}
Errors met: E0425
- 1.4 Chatterbox says hello
- Combine println! and format! into one small program
- 1.5 Reading what the compiler says
- Find the error code, the file, the line and the column in a compiler message
Errors met: E0308
- 1.6 Functions
- your own functions (fn)
fn print_banner() { - &str (text a function can read)
fn greeting(name: &str) -> String {
Errors met: E0061
- your own functions (fn)
- 1.7 Chapter review: Hello
- Predict what a short program prints, or which error stops it, without running it
Chapter 2: Values
At the end of it, Chatterbox knows its name, counts, and has settings.
- 2.1 Names for values
- let
let bot = "Chatterbox";
- let
- 2.2 Values that change
- mut
let mut messages_seen = 0;
Errors met: E0384
- mut
- 2.3 Numbers and true/false
- number types (i32, u32, usize, f64…)
let max_len: usize = 200; - true / false
let quiet: bool = false;
- number types (i32, u32, usize, f64…)
- 2.4 How big a number can get
- Work out how many values fit in a number of bits, and read a type name like u32 or i8
- 2.5 Text
- String (text that can grow)
let mut message = String::from("Hello"); - calling a method (value.method())
message.push_str(", world");
- String (text that can grow)
- 2.6 Pairs and constants
- const
const BOT: &str = "Chatterbox"; - tuples (.0, .1)
println!("major {}, minor {}", version.0, version.1);
- const
- 2.7 Chapter review: Values
- Predict what a short program with names, numbers and text prints, or why it stops
Chapter 3: Decisions
At the end of it, Chatterbox reads what you type and answers it.
- 3.1 Choosing with if
- if / else
if message.is_empty() {
- if / else
- 3.2 Choosing with match
- match
match message {
- match
- 3.3 Doing things again
- loops (for, while, loop)
while retries > 0 {
- loops (for, while, loop)
- 3.4 Reading a line
- use (bringing a name in)
use std::io;
- use (bringing a name in)
- 3.5 Chapter review: Decisions
- Predict which branch, arm or loop turn runs in a short program
Chapter 4: Memory
At the end of it, Chatterbox has /again, /history and /say.
- 4.1 Where values live
- Say what the stack and the heap are, and which values go where
- 4.2 One owner, one key
- State the one-key rule in your own words
- 4.3 Handing over the key
- Explain what a move is in terms of the one key
Errors met: E0382
- 4.4 Borrowing
- borrowing with &
let loud = shout(&msg);
Errors met: E0502
- borrowing with &
- 4.5 Borrowing to change
- &mut (a borrow that can change)
fn record(log: &mut String, msg: &str) {
Errors met: E0499
- &mut (a borrow that can change)
- 4.6 Parts of a value
- slices ([a..b])
let cmd = &msg[..4];
- slices ([a..b])
- 4.7 Chapter review: Memory
- Say, for each line of a short program, who owns a value and who is only borrowing it
Chapter 5: Shapes
At the end of it, Chatterbox has real Message and Command types.
- 5.1 Bundling fields: struct
- struct
struct Message {
- struct
- 5.2 Giving a struct behaviour
- impl and self
impl Message {
- impl and self
- 5.3 One of several: enum
- enum
enum Command {
- enum
- 5.4 Maybe nothing: Option
- Option (Some / None)
fn find_command_arg(line: &str) -> Option<&str> { - .unwrap()
io::stdin().read_line(&mut name_line).unwrap();
- Option (Some / None)
- 5.5 Patterns
- if let, | in patterns, #[derive(Debug)]
while let Some(i) = rest.find(' ') {
Errors met: E0004
- if let, | in patterns, #[derive(Debug)]
- 5.6 Chapter review: Shapes
- Tell a struct from an enum, and pick the right one for a new piece of data
Chapter 6: Collections
At the end of it, Chatterbox has /remember, /find and /stats.
- 6.1 A list: Vec
- Vec
let mut names: Vec<String> = Vec::new();
- Vec
- 6.2 Walking a list
- .iter() and .enumerate()
for (i, text) in history.iter().enumerate() {
- .iter() and .enumerate()
- 6.3 Lookup by key: HashMap
- HashMap
use std::collections::HashMap;
- HashMap
- 6.4 Small functions on the spot
- closures (|x| …)
let double = |n: u32| n * 2;
- closures (|x| …)
- 6.5 Iterators
- iterator steps (.map, .filter, .collect, .sum)
let lengths = history.iter().map(|m| {
- iterator steps (.map, .filter, .collect, .sum)
- 6.6 Chapter review: Collections
- Pick a Vec or a HashMap by the question you ask: by position or by name
Chapter 7: Errors and tests
At the end of it, Chatterbox reports clear errors, has its own tests and passes clippy.
- 7.1 Operations that can fail: Result
- Result (Ok / Err)
Ok(n) => println!("count is {n}"),
- Result (Ok / Err)
- 7.2 The ? operator
- the ? operator
let n = arg.trim().parse::<u32>()?;
- the ? operator
- 7.3 Writing tests
- tests (#[test])
#[cfg(test)]
- tests (#[test])
- 7.4 Tools that check your code
- Format a project with cargo fmt and check it with cargo fmt --check
- 7.5 Chapter review: Errors and tests
- Predict whether a program with Result and ? compiles, and what it prints, without running it
Chapter 8: Organising code
At the end of it, Chatterbox lives in several files, saves its history and can swap who replies.
- 8.1 Splitting code into files
- mod, pub and crate::
mod message {
Errors met: E0616
- mod, pub and crate::
- 8.2 Saving and loading
- files (std::fs)
match fs::read_to_string(path) {
- files (std::fs)
- 8.3 Code for any type: generics
- generics (<T>)
fn last_n<T>(items: &[T], n: usize) -> &[T] {
Errors met: E0369
- generics (<T>)
- 8.4 Traits
- trait, dyn and Box
trait Replier {
- trait, dyn and Box
- 8.5 How long a borrow lasts
- lifetimes ('a)
fn longer<'a>(a: &'a str, b: &'a str) -> &'a str {
Errors met: E0106
- lifetimes ('a)
- 8.6 Chapter review: Organising code
- Predict whether a program with modules, generics, traits or lifetimes compiles, and what it prints
Chapter 9: The real model
At the end of it, Chatterbox talks to a real AI model.
- 9.1 JSON with serde
- serde (JSON)
use serde::{Deserialize, Serialize};
- serde (JSON)
- 9.2 One HTTP call
- reqwest and environment variables
Http(reqwest::Error),
- reqwest and environment variables
- 9.3 Ship it
- Run your program's own tests with cargo test
- 9.4 Chapter review: The real model
- Predict what serde writes for a struct or a list, and when reading JSON fails
Chapter 10: Streaming replies
At the end of it, Chatterbox shows answers as they are written, and Ctrl-C stops a long one.
- 10.1 Waiting without freezing
- async, .await and tokio
async fn greet(name: &str) -> String {
Errors met: E0728
- async, .await and tokio
- 10.2 Tasks and channels
- tasks and channels (spawn, mpsc)
use tokio::sync::mpsc;
Errors met: E0373
- tasks and channels (spawn, mpsc)
- 10.3 Streaming the real model
- Ask a chat API for a streamed answer and recognise the server-sent event lines it sends back
- 10.4 Stopping a long answer
- select! and Ctrl-C
tokio::select! {
- select! and Ctrl-C
- 10.5 Chapter review: Streaming replies
- Predict when an async fn runs, what tokio::join! hands back, and when a channel closes
Compiler errors have their own page: the compiler error atlas. To make it stick, review the flashcards.