Skip to content

A Less Mad March

Tag: #rust

Why use Rust on the backend?

I read and liked Andrew Israel's I love building a startup in Rust. I wouldn't pick it again. It makes a lot of sense! He basically says that his startup prioritizes developer productivity over performance. Sensible choice for a start-up founder to make. If Rust is going to slow your developers down, and you don't need its benefits, then you should definitely consider using a different language.

On the other hand, I've been using Rust as high-level language at Cloudflare for a few years now. By "a high-level language" I mean one where performance doesn't really matter much. I've mostly been using it for API servers, where overall latency doesn't really matter too much. I'd be totally fine using a garbage collected language, or an interpreted language, because I don't need to eke out every last microsecond for blazing fast performance. I just want my server to stay up, do its job, and let me ship features quickly.

So why use Rust for a task like that? Well, although Rust has a reputation for being a low-level systems language, it actually does an admirable job of acting like a high-level language. So here's my list of reasons to consider using Rust, even for a project where performance isn't critical.

Illegal satire about Rust

In case you didn't hear, comedy is now legal on Twitter but accounts engaged in parody must include “parody” in their name, not just in bio. Of course, this only made everyone double down. So yesterday, I changed my name to Rust Language and started posting misinformation.

Tweet from my personal Twitter, changed to impersonate the official Rust twitter. The tweet says "We're adding a fifth string type called "Strang". It's subtly different to String but we're not going to tell you how."

The last week on twitter has basically been "the new 3rd grade substitute teacher can't control the class" and we're all misbehaving. I've changed my twitter back to my real name and face, so I've preserved my fake Rust tweets for posterity here.

What are Rust's HTTP extensions?

I learned about extensions when reading the hyper docs. But they also pop up in lots of other Rust web libraries, like http, tonic, and actix-web. So they must be really useful, if so many libraries offer them. But I personally had no idea what they were or how to use them. Today I'm going to explain what extensions really are (a set of values, keyed by type), and how you can use them to pass data between different parts of your web servers (e.g. middleware, routers, and handler functions). I'll give you a real-world example from the gRPC server I'm building at my job.

Parsing bitstreams with Nom

Programming languages generally only manipulate bytes (groups of 8 bits). It can be pretty tricky to manipulate single bits. But sometimes you need to -- for example, a DNS header has some 4-bit numbers, and encodes some boolean flags into single bits. So we really need a way to parse binary data without chunking it up into bytes of 8 bits.

Luckily, Nom can do this! In the last blog post, we learned how to parse text files with Nom. The trick is to start with simple parsers that parse a few characters at a time. Then, using combinators, combine those simple parsers into more complex parsers that can deserialize an entire structured file. We can reuse this approach for parsing binary data too. Let's see how!

Parsing Text with Nom

"Parsing" is turning a stream of raw text or binary into some structured data types, i.e. a Rust type that your code can understand and use. This isn't the textbook definition of parsing, but damnit, this is my blog and my opinion. This tutorial is about nom, my favourite Rust parsing library. It uses a parser combinator approach: you start writing tiny parsers that match, say, a single number or a character. These become building blocks for larger parsers, that match, say, a date or a phone number. By combining many small parsers together, you can build a big parser that decodes a file or stream into nice Rust structs and enums. In this tutorial we'll use Nom to parse the input file to an Advent of Code puzzle.

Pin, Unpin, and why Rust needs them

Using async Rust libraries is usually easy. It's just like using normal Rust code, with a little async or .await here and there. But writing your own async libraries can be hard. The first time I tried this, I got really confused by arcane, esoteric syntax like T: ?Unpin and Pin<&mut Self>. I had never seen these types before, and I didn't understand what they were doing. Now that I understand them, I've written the explainer I wish I could have read back then. In this post, we're gonna learn

  • What Futures are
  • What self-referential types are
  • Why they were unsafe
  • How Pin/Unpin made them safe
  • Using Pin/Unpin to write tricky nested futures