14 days of Rust

I wanted to get hands-on and finally spend time with Rust. Figured two weeks was a solid enough time to spend daily reading and coding. I asked Claude to give me a plan and here it is.

9 years 4 months 6 days since last time I wrote a post, a lot has happened in between but right now I'm writing Rust so that will be the focus for a while.

I told Claude I was coming from zero and wanted to be able to write CLI, TUI and a simple Markdown → HTML formatter by the end. I like to use Exercism to give me hands on experience, and I'm using the Rust-Book from Brown after I watched this Will Crichton: Rust for Everyone!. Specifically seeing the Aquascope Playground explain borrow checking was cool.

The following is Claude's plan for 14 days of Rust, you can tell right away it's Claude. I wonder in a few years if it will sound different. Some formatting had to be fixed to render correctly here, but nothing about the content was changed.

14 Days of Rust — from zero to a working SSG

The deal

One project, three faces. You build a static site generator as a single crate:

PieceWhat it isDays
lib.rsMarkdown → HTML parser + site model8–10
src/main.rsssg build / ssg new CLI7, 13
src/bin/tui.rsBrowse pages, live-preview the render11–12

Everything before Day 7 is loading the magazine. Days 7–14 are the project.

Daily shape (~2h)

Two rules that don't change:

Rust Book chapter numbers shifted in the 2024 edition. Titles are stable — go by title if a number looks off.


Day 0 — before you start (15 min, today)


Week 1 — the language

Day 1 (Tue 11 Aug) — Cargo, syntax, the shape of a program

Read: Book ch. 1–3 (Getting Started, Guessing Game, Common Programming Concepts)

Exercism: hello-world, two-fer, reverse-string, gigasecond

Done when: you can explain why let x = 5; x = 6; fails and let x = 5; let x = 6; doesn't.


Day 2 (Wed 12 Aug) — Ownership, borrowing, slices

Read: Book ch. 4 (Understanding Ownership) — slowly. This is the chapter.

Exercism: raindrops, acronym, pangram, scrabble-score

Done when: you can say what fn longest(a: &str, b: &str) -> &str is missing without looking it up. (You'll fix it on Day 6.)


Day 3 (Thu 13 Aug) — Structs, enums, pattern matching

Read: Book ch. 5–6 (Structs, Enums and Pattern Matching)

Exercism: space-age, high-scores, allergies

Nothing here needs a hand-written trait impl yet — traits are Day 6, and clock waits until then.

Done when: match on an enum feels better than a chain of ifs. Keep that enum sketch; it becomes Block on Day 8.


Day 4 (Fri 14 Aug) — Collections + module system

Read: Book ch. 7 (Managing Growing Projects) and ch. 8 (Common Collections)

Exercism: word-count, nucleotide-count, etl

Done when: you know why src/main.rs calls mycrate::foo() and not crate::foo().


Day 5 (Sat 15 Aug) — Error handling

Read: Book ch. 9 (Error Handling)

Crates: cargo add anyhow thiserror in a scratch project

Exercism: luhn, matching-brackets, roman-numerals

Done when: you can convert a function from unwrap()-everywhere to ?-everywhere without thinking.


Day 6 (Sun 16 Aug) — Generics, traits, lifetimes, tests

Read: Book ch. 10 (Generic Types, Traits, Lifetimes) and ch. 11 (Writing Automated Tests)

Exercism: clock (this is your impl Display + operator-trait exercise), sublist (generics + bounds), triangle

Done when: you've written a generic function with a trait bound that compiles on first try.


Week 2 — the build

Week 2 is project-dominant: ~30 min reading, ~90 min building. Exercism entries below are optional — do them only if the project work finished early.

Day 7 (Mon 17 Aug) — CLI skeleton + pin the scope

Read: Book ch. 12 (An I/O Project: Building a Command Line Program) — build minigrep fully. Best 90 minutes in the Book. If time is tight, read it and build the argument-parsing half only.

Project — mdssg is born:

Write SPEC.md — this is the important half of today. Fifteen lines, no more, stating exactly what your markdown dialect supports and what it doesn't. Draft:

Supported:  ATX headings (# .. ######), paragraphs, fenced code (``` with optional lang),
            thematic breaks (---), unordered lists (- *), ordered lists (1.),
            blockquotes (>), inline: *em* **strong** `code` [link](href) ![img](src), \escapes
Not supported: setext headings, reference links, HTML passthrough, tables,
            nested lists, lazy continuation, autolinks, footnotes

Done when: cargo run -- build --input content lists your markdown files, and SPEC.md has a line you can point at whenever you're tempted to add a feature.


Day 8 (Tue 18 Aug) — Iterators + block parser, part 1

Read: Book ch. 13 (Iterators and Closures)

Project — the flat blocks only (src/parser/block.rs):

Exercism (optional): accumulate

Done when: those four block types parse correctly and their fixtures are the first ones passing.


Day 9 (Wed 19 Aug) — Inline parser + HTML renderer

Read: Rust By Example §"Strings", plus the std::str and char docs. Skim pulldown-cmark's docs to see how the pros model events — don't add it as a dependency; you're writing this one.

Project — inlines and the first real HTML:

Exercism (optional): anagram

Done when: md_to_html("# Hi\n\nsome **bold** text") produces exactly the HTML you'd hand-write.


Day 10 (Thu 20 Aug) — Recursive blocks + catch-up day

Read: Book ch. 15 (Smart Pointers)

This is the slack day. If Days 8–9 overran, spend the whole session finishing them and skip everything below except the last two boxes. Nothing downstream depends on lists or links.

Project — the recursive cases:

Done when: every fixture from Day 7's SPEC.md passes, or you've knowingly moved a line from "supported" to "not supported" and deleted its fixture.


Day 11 (Fri 21 Aug) — TUI: the event loop

Read: the ratatui book — Getting Started + the "Hello World" and "Counter" tutorials

Project — src/bin/tui.rs:

Done when: you can navigate the file list and quit cleanly, with your terminal intact.


Day 12 (Sat 22 Aug) — TUI preview, then earn the abstraction

Read: the trait-objects / OOP chapter (ch. 17 or 18 depending on edition) — dyn Trait vs. generics, static vs. dynamic dispatch

Project — build it concrete, then refactor:

Done when: one parser feeds two renderers through one trait, and you can browse a folder of markdown rendered in your terminal.


Day 13 (Sun 23 Aug) — The full build pipeline

Read: Book ch. 14 (More About Cargo and Crates.io) — profiles, workspaces, features

Project — turn a parser into an SSG:

ssg serve with file-watching is not in the 14 days — it's a whole evening of notify plus a socket server. It's first on the after-Day-14 list.

Done when: ssg build turns a folder of markdown into a site you can open in a browser.


Day 14 (Mon 24 Aug) — Ship it

Project:

Retro — write real answers:

Done when: it's tagged, documented, and you'd show it to someone.


After Day 14 — where to go next


Reference

Crates you'll install

CrateForDay
clap (derive)CLI args7
anyhowerror handling in binaries5, 7
thiserrorerror types in the library5, 10
walkdirrecursive file discovery7
ratatui + crosstermTUI11
serde + tomlfrontmatter13

Deliberately not used: pulldown-cmark, comrak, any template engine. Writing those is the point.

The loop that matters

cargo check → fix → cargo testcargo clippy → commit. Every day.

When you're stuck

  1. Read the full error. Rust's errors are essays; the fix is usually in the help: line.
  2. rustc --explain E0502 (or whatever the code is).
  3. Draw the ownership on paper — who owns it, who borrowed it, when does each drop?
  4. Ask "what would this look like with no references at all?" Get it compiling with .clone(), then remove clones one at a time.

Triage — when you fall behind

Days 8–10 are the parser and they will be the tight ones. In priority order:

  1. Never cut Days 8–9. Headings, paragraphs, code blocks, and basic inlines are the whole spine.
  2. Day 10 is the buffer. Spend all of it on unfinished Day 8–9 work if needed. Lists, quotes and links are optional — move them to "not supported" in SPEC.md and delete their fixtures.
  3. Then cut Day 12's polish (scrolling, focus switching, reload) before cutting the trait extraction — the refactor is the lesson.
  4. Last resort: ship the CLI and parser without the TUI. Two of three faces is a real result.

Cut the Exercism block before the project block, always.

Rules for this fortnight

Exercism note

Exercise names occasionally move or get retired on the Rust track. If one isn't there, pick the nearest equivalent from the same concept group — the concept is what matters, not the specific exercise.