Learn Rustfrom a coach.Not from a video.

Every lesson is written for you, from what you already know and what you got wrong last time. It hands you an assignment, runs your tests and reviews the code you actually wrote.

From reading Rust to writing it.Five steps, all with a coach beside you.

01

A lesson written for you, not a template

There is no lesson 7 that everyone gets. The coach reads its notes on you, re-tests what you got wrong last time, then teaches one idea with examples you can run, checking every few explanations that it landed.

Coach

Length in bytes of the first word, or None if there is none. You reached for indexing last time; try a combinator.

rust
fn first_word_len(text: &str) -> Option<usize> {
    text.split_whitespace().next().map(str::len)
}
run_tests
  • first_word
  • empty_string
  • leading_spaces
Review: no unwrap, one combinator chain. Signed off.3 passed
02

Ask the moment you are lost

Stop the lesson mid-sentence: “wait, why &str and not String?” The coach answers in the context of the code on screen, then picks up where you left off. No question is too small, and any topic you have covered is one click away.

Coach

So first_word takes a string and hands back a slice of it, without copying a single byte…

Wait, why &str and not String? I thought strings were String.

Coach

String owns its bytes; &str only borrows them. Taking &str means the function accepts a String (as &s) and a literal like "hi" alike, and never takes your string away from you.

Back to where we were: the slice we return points into the caller's string, so…

03

You write every line

Every lesson ends with an assignment you write yourself in the browser editor, and the tests decide when it is done. Stuck? Hints point at the API to reach for, and the trace steps through your function line by line. Never the answer.

src/lib.rs·17 lines Trace onHints on
7pub fn initials(name: &str) -> Option<String> { 8 let mut words = name.split_whitespace(); 9 let first = words.next()?; first ="ada"words =SplitWhitespace { … }name ="ada lovelace" 10 let last = words.last()?; 11 let a = first.chars().next()?; 12 let b = last.chars().next()?;
initialstest initials_ok · step 3 of 10Next
04

Reviewed like a pull request

Passing tests is where review starts. The coach reads the code you actually wrote and holds it to how Rust is written professionally: no stray unwrap, combinators over nested match, clippy clean, cargo fmt applied. You fix it until it is signed off.

Review · parse_pair

All three tests pass. Two things before I sign it off:

  1. line 11.unwrap() on the first character panics on an empty word. The function already returns Option: use ?.
  2. lines 9–14Two nested match on Option read as one step: first.zip(last).
  3. clippyneedless_return on line 15. The last expression is the return value.
Fix, run the tests, resubmit.Changes requested
05

Nothing is marked done until it sticks

Mastery rises with right answers and falls with wrong ones. Shaky topics come back as a redo, and review cards return at 1, 3, 7, 14, 30 and 60 days. The coach keeps notes on what stuck, so the next lesson starts from there.

Ownership and move semantics

Taught the single-owner model and moves on assignment. Answered all three check questions; needed one correction on Copy vs Drop.

Copy vs Clone

Derives Copy on his own types now. clone_from still untaught.

References and borrowing rules

Passed all 9 tests first try. Re-test that he picks &mut [T] when the length is unchanged.

Slices (&str, &[T])

Built around the ways people actually get stuck.

Small tools, each one for a moment where you would otherwise be on your own.

Quick check

Which line moves s instead of borrowing it?

Alet t = &s; Blet t = s; Clet n = s.len();
Right.

Assigning a String to a new binding moves it; &s and a method call only borrow.

Quick checks

Every few explanations the coach asks one question. Click, see why, and the lesson picks up from your answer.

Build failed Explain with the coach
  • E0382borrow of moved value: wordsline 9

    WHATLine 8 handed words to next() by value, so by line 9 there is nothing left to borrow.

    TRYLook at what an iterator's next takes: &mut self. The binding needs to allow that.

Compiler error coach

A failed build lists each rustc error and tints the line. One click explains, in plain English, what went wrong and what to try next. The fix stays yours.

src/lib.rs·21 lines3 clippy notes
14 let unused = 1; 15 if out.len() == 0 { return None; } 16 return Some(out); 17}
clippy · len_zero

length comparison to zero

  • using is_empty is clearer and more explicit

About len_zero

Clippy as an additional teacher

Every test run also runs clippy. Each lint is a broom in the gutter with the message, the help and a link, and the review teaches the idiom behind one.

Review3 of 8·Chapter 2 · Copy vs Clone

What does this print?

let a = String::from("hi");
let b = a.clone();
println!("{a} {b}");
Acompile error: a moved Bhi hi Chi then a panic
Right.

clone makes a second String, so both bindings are still usable.

Back in 7 days.Next

Review cards

When a lesson ends, the coach writes two cards per topic it signed off. They come back at 1, 3, 7, 14, 30 and 60 days. A miss brings one back tomorrow.

Stretch challenge

Accepted. Now make initials work without to_ascii_uppercase allocating twice: one String, built once.

StretchOptional.Skip it

Stretch challenges

Solution accepted? One optional refactor. Extra credit, never part of the sign-off.

src/lib.rsscratch.rs
1fn main() {2 let v = vec![3, 1, 2];3 println!("{:?}", v.iter().max());4}
RunRan
Some(3)

A scratch file

scratch.rs next to the assignment. cargo run in the same sandbox, nothing graded, saved between visits.

3let first = words.next()?;4let last = words.last()?;
Explain⌘⇧E
Coach

? on an Option returns None from the whole function, so these two lines are also the "fewer than two words" guard.

Explain this selection

Select code, press one shortcut, and the coach explains it in the lesson.

7days in a row
Chapter 2

Ownership and borrowing

Mastery 85%
Chapter 2 complete.

Streaks and mastery

A day counts when you chat, run tests or answer a card. Mastery rises with sign-offs and right answers, and falls with wrong ones.

Sixteen chapters, in the order Rust wants to be learned

Bindings before ownership, ownership before borrowing, borrowing before lifetimes. Each chapter ends when the coach signs it off, not when you finish reading.

    Buy it like a book. Use it like a coach.

    No subscription. You buy credits once and they never expire. A typical lesson uses about one credit; a long conversation or a redo uses a bit more, a quick one less. Nothing is ever cut short.

    Free start
    The Course
    Top-up
    Price
    $0
    $49once
    $10or $25
    Credits
    1, no card needed
    50, enough for the whole syllabus if you already program a bit in another language
    10 or 30 more, once you own the Course
    All 16 chapters, every feature
    Coach hints and line-by-line trace
    Code review on every submit
    Quick checks, review cards, streaks
    Expires
    never
    never
    never
    Top up

    $49 once, not $20 a month. Card payments via Stripe, plus VAT where it applies. Credits are non-refundable except where the law requires otherwise.

    Terms and conditions apply.

    Sign in

    Continue with Google No account? Register · Forgot password?

    Create your account

    Continue with Google Already registered? Sign in

    Reset your password

    Back to sign in

    Choose a new password

    Back to sign in
    Assignment
    Tests (read-only)
    ·0 lines

    Run tests to see results here.

        Raw output

        History

        Keyboard shortcuts

        Do a topic again

        A new lesson on it, written from where you are now. The coach re-tests you first. The old lesson stays in your history.