Rust Beyond Systems Programming
The case that Rust is a good choice for ordinary applications — tools, services, desktop software — and not only for systems work.
8 parts published so far.
Parts
Write like TypeScript, deploy like Go
I learned Rust by building a bank in it, having never written a line of it before, while the corridor explained that Rust needs PhD-level programmers. What actually changed was not safety. It was relief: I stopped spending my day avoiding mistakes and got to spend it solving the problem.
Put it next to what you already write
The things you actually like about TypeScript, Java, Python and Go — unions, Optional, streams, lambdas, promises, channels, one command that builds everything — and where every one of them lives in Rust. No complaints in this one. Just the shape of an ordinary working day.
The errors you are never going to see again
NullPointerException. Cannot read properties of undefined. ConcurrentModificationException. Segmentation fault. A tour of the failures that have nowhere left to happen once the types stop evaporating — and an honest account of the ones that stay.
A converter is a small compiler
An empty directory becomes a Rust project: why a file-to-file converter is shaped like a compiler, a library and a binary in one package, modules and who can see them, a manifest with no dependencies in it, two lines that let the build refuse undocumented and unsafe code, and CI on three operating systems from the very first commit.
Arguments, without writing a parser
postres learns to listen, and we write no parser to make it happen: the command line described as a struct, a macro that writes the parser from it — help screen and typo suggestions included — and what structs, attributes and macros are, and why they make Rust feel like a high-level language.
Optional for the user, not for us
Some and None turn out to be an enum — and not the kind Java has. Tagged unions, an Option that cannot pass for the value it might hold, inputs kept apart from the domain, and a Config the rest of postres can trust: private, settled once built, and named even when the user does not name it.
Is that name right?
postres picks a default output name, and one run showed it can be wrong. Tests that say what right means, a regular expression that fails them twice, the fix that was in the standard library all along — and a rule that would have found it first.
Now, later, or only in tests
Three ways to hand code around — a block that runs now, a closure that runs later, a function with a name — and how to choose. Tests that become a table. And conditional compilation: code decided before the program runs, and why that is safer than deciding it while it runs.
A log that does not block
Not published yet
Why printing is synchronous, what a non-blocking writer does about it, what that costs when nobody measures — and the one-character mistake the compiler itself recommends.
Reading the collection
Not published yet
JSON with hundreds of optional fields, parsed into types. Where a String lives, where a &str points, and why they are two different things.
Saying what went wrong
Not published yet
An error type the program can name, Result end to end, and the difference between a failure you can explain and one you can only report.
Methods and traits
Not published yet
A string arrives and has to become something the program cannot get wrong. Traits where another language would reach for inheritance.
The request and its builder
Not published yet
A value assembled in stages, the builder written by hand and then derived — and the story of a fork, a rejected pull request, and the better answer the maintainer gave.
Bodies
Not published yet
One thing that is several shapes, each with its own optional parts: pattern matching and destructuring on data that genuinely varies.
The output has nowhere to live
Not published yet
The program understands a request and still cannot produce anything, because nothing can hold the result. A tree with parents in it, and what it costs.
Lowering
Not published yet
Turning one model into another without copying everything and without the compiler refusing the program. Borrowing, lifetimes, and clone as a legitimate first answer.
Walking the tree
Not published yet
Every later step needs to visit every request. Implementing Iterator by hand, and then iterators in general on a structure that is not a list of numbers.
Passes, and writing the file
Not published yet
Inherited settings, composed names, and then the writer. The first time the program produces output, four years after it was started.
Shipping
Not published yet
A tool nobody can install is not a tool. Binaries for three platforms, one command to install it, and the closing measurement.