Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/links.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Links

on:
push:
branches: [master]
pull_request:
# Catch link rot on a schedule, not just when something changes.
schedule:
- cron: "0 6 * * 1" # Mondays, 06:00 UTC
workflow_dispatch:

# Don't pile up redundant runs on the same branch.
concurrency:
group: links-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
link-check:
name: Check links
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Zola
env:
ZOLA_VERSION: "0.22.1"
run: |
curl -sSfL "https://github.com/getzola/zola/releases/download/v${ZOLA_VERSION}/zola-v${ZOLA_VERSION}-x86_64-unknown-linux-gnu.tar.gz" \
| sudo tar -xz -C /usr/local/bin
zola --version

- name: Build site
run: zola build

# Speed up repeat runs and avoid re-hitting every external host.
- name: Restore lychee cache
uses: actions/cache@v4
with:
path: .lycheecache
key: lychee-${{ github.sha }}
restore-keys: lychee-

- name: Check links
uses: lycheeverse/lychee-action@v2
with:
# Resolve internal links to the freshly built files: --root-dir maps
# root-relative paths (/blog/...), --remap maps the absolute
# corrode.dev URLs the templates emit. Everything else is checked
# over the network.
args: >-
--config lychee.toml
--cache
--max-cache-age 1d
--root-dir "${{ github.workspace }}/public"
--remap "https://corrode.dev file://${{ github.workspace }}/public"
"public/**/*.html"
"public/llms.txt"
fail: true
2 changes: 1 addition & 1 deletion content/blog/rust-learning-resources-2026/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ It's like having a personal trainer for your Rust learning journey.
My workshops are designed to be hands-on and tailored to the needs of the participants.
I want people to walk away with a finished project they can extend.

All course material is open source and freely available on GitHub:
All the material is open source and free. You can browse the [full workshop catalog](/workshops/), or jump straight to a few favorites on GitHub:

- [Write Yourself a CLI](https://github.com/corrode/write-yourself-a-cli) - Create a tool to find files on your system
- [Write Yourself a Web App](https://github.com/corrode/write-yourself-a-web-app) - Build a small web app that shows weather data
Expand Down
8 changes: 2 additions & 6 deletions content/learn/_index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
+++
title = "Learn"
description = "A collection of resources, case studies, and guides to help you learn Rust and adopt it in your organization."
sort_by = "update_date"
insert_anchor_links = "heading"
template = "learn.html"
+++
redirect_to = "/learn/migration-guides"
+++
13 changes: 11 additions & 2 deletions content/learn/migration-guides/_index.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
+++
title = "Rust Migration Guides"
description = "Are you considering migrating from your current language to Rust? We've got you covered with guides that highlight the benefits of Rust and provide practical advice for making the switch. We'll help you navigate the transition."
description = "Considering a move to Rust? These practical, language-by-language guides cover the real-world benefits, the common pitfalls, and the patterns that make the transition smooth (written from hands-on consulting experience)."
sort_by = "date"
insert_anchor_links = "heading"
template = "migration-guides.html"
render = true
transparent = true
+++

Facing runtime crashes, long latencies, and rising infrastructure costs?
That's why so many teams are considering a move to Rust.
They want an actually helpful compiler that catches bugs in development, not production.
But the hard part isn't the syntax.
You need to map your language's idioms onto Rust's ownership model.
These language-specific guides, drawn from hands-on consulting work, show
where Rust pays off for your stack, how your concepts map across, and
when Rust is not the right choice.
1 change: 1 addition & 0 deletions content/learn/migration-guides/cpp-to-rust/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
+++
title = "C++ to Rust Cheat-Sheet"
description = "Memory safety without a garbage collector: a side-by-side map of C++ idioms and type equivalents to their Rust counterparts, from RAII to ownership."
date = 2025-05-17
updated = 2026-02-25
template = "article.html"
Expand Down
1 change: 1 addition & 0 deletions content/learn/migration-guides/go-to-rust/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
+++
title = "Migrating from Go to Rust"
description = "An opinionated look at what Rust fixes (nil panics, missed data races, error handling, leaky generics), plus where to keep Go and how to migrate services incrementally."
date = 2026-05-21
updated = 2026-05-26
template = "article.html"
Expand Down
1 change: 1 addition & 0 deletions content/learn/migration-guides/java-to-rust/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
+++
title = "Migrating from Java to Rust"
description = "An enterprise-grade playbook: planning the migration, running mixed Java/Rust codebases, and the mindset shifts from objects and inheritance to ownership."
date = 2024-12-09
updated = 2026-01-02
template = "article.html"
Expand Down
1 change: 1 addition & 0 deletions content/learn/migration-guides/python-to-rust/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
+++
title = "Migrating from Python to Rust"
description = "Where Python hits its limits (performance, type safety, deployment, resource usage) and how Rust addresses each without giving up Python's ergonomics."
date = 2024-12-13
updated = 2026-04-14
template = "article.html"
Expand Down
1 change: 1 addition & 0 deletions content/learn/migration-guides/scala-to-rust/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
+++
title = "Migrating from Scala to Rust"
description = "The business case for leaving the JVM: adoption momentum, rock-solid backward compatibility, and tooling, compared honestly against Scala and Clojure."
date = 2024-12-09
template = "article.html"
draft = false
Expand Down
1 change: 1 addition & 0 deletions content/learn/migration-guides/typescript-to-rust/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
+++
title = "Migrating from TypeScript to Rust"
description = "You already think in types. This guide maps TypeScript's interfaces, union types, and Promises straight onto Rust's traits, enums, and async."
date = 2024-12-13
updated = 2026-04-10
template = "article.html"
Expand Down
3 changes: 3 additions & 0 deletions content/learn/workshops/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
+++
redirect_to = "/workshops"
+++
3 changes: 3 additions & 0 deletions content/migrate/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
+++
redirect_to = "/learn/migration-guides"
+++
12 changes: 12 additions & 0 deletions content/workshops/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
+++
title = "Rust Workshops"
description = "Hands-on, project-based Rust workshops from corrode. The materials are free and open on GitHub. Work through them solo, or book one for your team."
template = "workshops.html"
insert_anchor_links = "heading"
+++

My workshops are hands-on: instead of toy snippets, you learn idiomatic Rust by
writing real code. Whether that's building an actual thing (a CLI, a shell, a web
app, a test suite) or solving interactive exercises Rustlings-style. Every
workshop is free and open-source on GitHub, spans beginner to advanced, and can
be booked as a live, tailored session for your team, on-site or remote.
77 changes: 77 additions & 0 deletions data/workshops.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Workshops shown on the Workshops page (/workshops), in listed order.
# The interactive course leads, then the repo workshops (Beginner first).
#
# Each entry is self-contained: `tags` and `meta` render as-is, so the course
# and the repo workshops can show different details. `meta` is a point-in-time
# snapshot (last checked 2026-06) — refresh it now and then. `pick` is a
# one-line "who is this for" nudge. `image` is the card thumbnail.

[[workshop]]
title = "A Beginner's Guide to Rust"
url = "https://course.corrode.dev/"
description = "An interactive course you take in your browser: write real code, get instant compiler feedback, and build fluency one small exercise at a time."
pick = "Small exercises with instant feedback."
level = "Beginner"
tags = ["Interactive", "In your browser"]
meta = "★ 12 · 20+ exercises · Free"
image = "https://opengraph.githubassets.com/main/corrode/course"

[[workshop]]
title = "Learning Rust by Counting Words"
url = "https://github.com/corrode/learning-rust-by-counting-words"
description = "Build <code>wc</code>, a little tool that counts words, lines, and characters. A gentle, practical introduction to Rust."
pick = "Start here if you've never written Rust and prefer a project-based approach."
level = "Beginner"
tags = ["Fundamentals", "2 hours"]
meta = "★ 6 · Updated Aug 2024"
image = "https://opengraph.githubassets.com/main/corrode/learning-rust-by-counting-words"

[[workshop]]
title = "Write Yourself a CLI"
url = "https://github.com/corrode/write-yourself-a-cli"
description = "Build a fast file finder and learn how to structure a real-world Rust CLI, plus a few advanced patterns along the way."
pick = "Pick this if you want to build a real command-line tool from scratch."
level = "Beginner"
tags = ["CLI", "Half day"]
meta = "★ 33 · Updated Apr 2025"
image = "https://opengraph.githubassets.com/main/corrode/write-yourself-a-cli"

[[workshop]]
title = "Write Yourself Some Tests"
url = "https://github.com/corrode/write-yourself-some-tests"
description = "Learn to write effective, ergonomic tests in Rust, from unit tests to the patterns that keep a suite maintainable."
pick = "Pick this if your code works but your tests feel messy or brittle."
level = "Beginner"
tags = ["Testing", "2–3 hours"]
meta = "★ 6 · Updated Mar 2025"
image = "https://opengraph.githubassets.com/main/corrode/write-yourself-some-tests"

[[workshop]]
title = "Writing Better Rust"
url = "https://github.com/corrode/refactoring-rust"
description = "A refactoring workshop: take working but rough Rust and reshape it into idiomatic, ergonomic, maintainable code, one step at a time."
pick = "Pick this if you can write Rust but want it to read like an expert wrote it."
level = "Intermediate"
tags = ["Refactoring", "Half day"]
meta = "★ 83 · Updated Jun 2026"
image = "https://opengraph.githubassets.com/main/corrode/refactoring-rust"

[[workshop]]
title = "Write Yourself a Shell"
url = "https://github.com/corrode/write-yourself-a-shell"
description = "Build a working shell from scratch. A deep dive into intermediate Rust concepts and idiomatic code."
pick = "Pick this if you want to go deep on systems concepts in Rust."
level = "Intermediate"
tags = ["Systems", "6 hours"]
meta = "★ 44 · Updated Nov 2024"
image = "https://opengraph.githubassets.com/main/corrode/write-yourself-a-shell"

[[workshop]]
title = "Write Yourself a Web App"
url = "https://github.com/corrode/write-yourself-a-web-app"
description = "Build a small web application with axum and Postgres to learn how the pieces of a Rust backend fit together."
pick = "Pick this if you're building web backends with axum and Postgres."
level = "Intermediate"
tags = ["Web", "Half day"]
meta = "★ 31 · Updated Mar 2025"
image = "https://opengraph.githubassets.com/main/corrode/write-yourself-a-web-app"
45 changes: 45 additions & 0 deletions lychee.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
################################################################################
# lychee link checker configuration.
#
# Used by .github/workflows/links.yml against the built site in ./public.
# Internal links (corrode.dev and root-relative) are remapped to the local
# build in CI, so this run validates both internal wiring and external links.
#
# Docs: https://github.com/lycheeverse/lychee
################################################################################

# Be patient with slow or rate-limited hosts before giving up.
max_retries = 2
retry_wait_time = 3
timeout = 20
max_concurrency = 12

# Plenty of hosts answer automated traffic with 403/429 even when the link is
# fine. 405 means the URL exists but doesn't allow GET/HEAD (e.g. the
# newsletter form's POST-only endpoint). Treat all of these as a pass.
accept = ["200..=299", "403", "405", "429"]

# Look like a normal browser. Cuts down on bogus 403s from bot-averse hosts.
user_agent = "Mozilla/5.0 (compatible; corrode-link-check; +https://corrode.dev)"

# The site obfuscates mailto: addresses with HTML entities, so skip them.
include_mail = false

# Don't try to reach localhost or private network addresses.
exclude_all_private = true

# Hosts that routinely block automated checks, or that we can't do anything
# about even when they break. Skip them to keep the signal clean.
exclude = [
# Internal links that carry a query string (e.g. podcast "?t=12:34" deep
# links). After the CI remap to local files, the "?" becomes part of the
# path and can't resolve. The target page is validated on its own.
'^file://.*%3F',
'^https?://(www\.)?linkedin\.com',
'^https?://(www\.)?twitter\.com',
'^https?://(www\.)?x\.com',
'^https?://t\.co/',
'^https?://(www\.)?reddit\.com',
'^https?://web\.archive\.org',
'^https?://([a-z0-9-]+\.)?amazon\.[a-z.]+',
]
Loading
Loading