The first stable release of Rust was on May 15, 2015, just about 9½ years ago. My first “production” Rust code was a Slack bot, which talked to GoCD to control the rollout of a web app. This was utterly reliable. And so new bits of Rust started popping up.

I’m only going to talk about open source stuff here. This will be mostly production projects, with a couple of weekend projects thrown in. Each project will ideally get its own post over the next couple of months.

Planned posts

Here are some of the tools I’d like to talk about:

  1. Moving tables easily between many databases (dbcrossbar)
  2. 700-CPU batch jobs
  3. Geocoding 60,000 addresses per second
  4. Interlude: Neural nets from scratch in Rust
  5. Lots of CSV munging
  6. Interlude: Language learning using subtitles, Anki, Whisper and ChatGPT
  7. Transpiling BigQuery SQL for Trino (a work in progress)

I’ll update this list to link to the posts. Note that I may not get to all of these!

Maintaining Rust & training developers

One of the delightful things about Rust is the low rate of “bit rot”. If something worked 5 years ago—and if it wasn’t linked against the C OpenSSL libraries—then it probably works unchanged today. And if it doesn’t, you can usually fix it in 20 minutes. This is largely thanks to Rust’s “stability without stagnation” policy, the Edition system, and the Crater tool which is used to nest new Rust releases against the entire ecosystem.

The more interesting questions are (1) when should you use Rust, and (2) how do you make sure your team can use it?

When should you use Rust? Rust shines for CLI tools, dedicated servers, and any code where you need to lay out a complex domain model very clearly. A lot of these programs are “reusable components” with stable interfaces. If you could imagine open-sourcing something, Rust is often an excellent choice.

But at least in my personal experience, Rust is more problematic for frequently-changing business logic. This is often because even Rust-friendly companies have a lot of people who work mostly in TypeScript, Python and other high-level languages. Crossing the barrier from those languages to Rust adds unnecessary friction to frequent business logic changes. That said, if your entire team knows Rust for other reasons, then this may be a non-issue.

How do you make sure your team can use Rust? In practice, I’ve rarely seen Rust positions advertised. Usually, if a company is going to use Rust, it has internal developers who are interested in learning it.

The people who make the jump fastest to Rust are those with several of the following skills:

  1. Knowledge of memory layout. Do they know the difference between the stack and the heap? Do they know what a pointer is? Can they explain what a struct might look like in memory, or the difference between “pass by value” and “pass by reference”? Rust forces you to make choices about how your data is laid out and passed around. This is great for performance, but it means that C, C++ and assembly programmers have a head start.
  2. Knowledge of basic functional programming tools like map and closures. Idiomatic Rust code uses iterators, map, filter and local functions a lot. This is common in JavaScript, Python, Ruby and many other high-level languages.
  3. At least some ability to adapt to “functional architecture.” But the subtlest issue for people learning Rust is figuring out how to structure programs. Any architecture which could be described as “a whole web of objects referring to each other and mutating each other” is going to hurt. Rust heavily prefers either (a) programs composed of functions that take inputs and transform them into outputs, or (b) functions that take exclusive ownership of something and mutate it. How much this hurts depends on what you’re writing. For a network service, the learning curve might be trivial. For a game, you might need to design your architecture from the ground up to work well with Rust.

Common tools and libraries

Rust is blessed with fantastic tooling and libraries. In addition to cargo (the package manager), some great tools and libraries include:

  1. cargo deny: Warns about security vulnerabilities and enforces licensing policies.
  2. serde: The de facto standard library for serializating and deserializing Rust data structures.
  3. Burntsushi’s csv library: CSV parsers are really basic things, but this one is solid, and it sees constant work.
  4. tokio: Tokio is the most popular async framework for Rust. There are pros and cons to uing async, but that’s a discussion for another day.
  5. clap: A command-line argument parser that can implement almost any standard CLI interface. It’s not the lightest-weight tool, but you can use it for almost anything.
  6. anyhow: For all those CLI tools where you just want to print exceptions and backtraces, and don’t want to fuss with maintaining error types.
  7. peg: Parser Expression Grammars (PEGs) for Rust, with precedence climbing. Now, this is a bit of an idiosyncratic personal choice. And PEGs are theoretically sketchy. But peg is well-implemented and polished, and if I need to parse simple- or medium-complexity grammars, I often reach for it.

Coming next

Over the next few weeks, I look forward to talking about lots of open source Rust projects, including many some have been in production for 5 to 10 years. I hope you’ll join me!