# Twtxt is an open, distributed microblogging platform that # uses human-readable text files, common transport protocols, # and free software. # # Learn more about twtxt at https://github.com/buckket/twtxt # # This is an automated Yarn.social feed running feeds v0.1.0@72e53a9 # Learn more about Yarn.social at https://yarn.social # # nick = fasterthanli-me # url = https://feeds.twtxt.net/fasterthanli-me/twtxt.txt # type = rss # source = https://fasterthanli.me/index.xml # avatar = # description = amos likes to tinker # updated_at = 2024-04-08T16:47:25Z # 2023-07-03T16:30:00Z **Cracking Electron apps open**
I use the [draw.io desktop app](https://github.com/jgraph/drawio-desktop) to
make diagrams for my website. I run it on an actual desktop, like Windows or
macOS, but the asset pipeline that converts `.drawio` files, to `.pdf`, to
`.svg`, and then to `.svg` again (but smaller) runs on Linux. ⌘ [Read more](https://fasterthanli.me/articles/cracking-electron-apps-open) 2023-05-31T21:00:00Z **The RustConf Keynote Fiasco, explained**
**Disclosure**:
At some point in this article, I discuss The Rust Foundation. I have received a
$5000 grant from them in 2023 for making educational articles and videos about
Rust.

I have NOT signed any non-disclosure, non-disparagement, or any other sort of
agreement that would prevent me from saying exactly how I feel about their
track record. ⌘ [Read more](https://fasterthanli.me/articles/the-rustconf-keynote-fiasco-explained) 2023-05-28T17:04:00Z **Rust: The wrong people are resigning**
(Note: this was originally posted [as a\
gist](https://gist.github.com/fasterthanlime/42da9378768aebef662dd26dddf04849))

## [Reassuring myself about Rust](\#reassuring-myself-about-rust) ⌘ [Read more](https://fasterthanli.me/articles/rust-the-wrong-people-are-resigning) 2023-03-05T07:30:12Z **Extra credit**
We've achieved our goals already with this series: we have a web service written
in Rust, built into a Docker image with nix, with a nice dev shell, that we can
deploy to [fly.io](https://fly.io).

But there's always room for improvement, and so I wanted to talk about a few
things we didn't bother doing in the previous chapters.

## [Making `clash-geoip` available in the dev shell](\#making-clash-geoip-available-in-the-dev-shell) ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-12) 2023-03-05T07:30:11Z **Generating a docker image with nix**
There it is. The final installment.

Over the course of this series, we've built a _very useful_ Rust web service
that shows us colored ASCII art cats, and we've packaged it with docker, and
deployed it to [https://fly.io](https://fly.io). ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-11) 2023-03-05T07:30:10Z **Making a dev shell with nix flakes**
In the previous chapter, we've made a nix "dev shell" that contained the fly.io
command-line utility, "flyctl".

That said, that's not how I want us to define a dev shell. ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-10) 2023-03-05T07:30:09Z **Learning Nix from the bottom up**
Remember the snapshot we made allll the way back in [Part 1](part-1)? Now's the time to use it.

Well, make sure you've committed and pushed all your changes, but when you're
ready, let's go back in time to before we installed anything catscii-specific in
our VM. ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-9) 2023-03-05T07:30:08Z **Doing geo-location and keeping analytics**
I sold you on some additional functionality for `catscii` last chapter, and we
got caught up in private registry / docker shenanigans, so, now, let's resume
web development as promised.

## [Adding geolocation](\#adding-geolocation) ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-8) 2023-03-05T07:30:07Z **Using the Shipyard private crate registry with Docker**
Wait wait wait, so we're not talking about nix yet?

Well, no! The service we have is pretty simple, and I want to complicate things
a bit, to show how things would work in both the Dockerfile and the nix
scenario. ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-7) 2023-03-05T07:30:06Z **Deploying catscii to fly.io**
**Disclosure**:
Because I used to work for fly.io, I still benefit from an employee discount
at the time of this writing: I don't have to pay for anything deployed there
for now.

fly.io is still [sponsoring me](/donate) for developing
[hring](https://github.com/hapsoc/hring), but this isn't a sponsored post. It's
just a good fit for what we're doing here, with a generous free tier. ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-6) 2023-03-05T07:30:05Z **Writing a Dockerfile for catscii**
Now that our service is production-ready, it's time to deploy it somewhere.

There's a lot of ways to approach this: what we are going to do, though, is
build a docker image. Or, I should say, an [OCI\
image](https://github.com/opencontainers/image-spec). ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-5) 2023-03-05T07:30:04Z **Serving ASCII cats over HTTP**
Our `catscii` program does everything we want it to do, except that it's a
command-line application rather than a web server. Let's fix that.

## [Enter `axum`](\#enter-axum) ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-4) 2023-03-05T07:30:03Z **Printing ASCII cats to the terminal**
Now that our development environment is all set up, let's make something useful!

## [Creating the `catscii` crate](\#creating-the-catscii-crate) ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-3) 2023-03-05T07:30:02Z **Developing over SSH**
With [the previous part](part-1)'s VM still running, let's try connecting to our
machine over SSH.

## [Network addresses, loopback and IP nets](\#network-addresses-loopback-and-ip-nets) ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-2) 2023-03-05T07:30:01Z **Setting up a local Ubuntu Server VM**
The first step to using Nix to build Rust is to do so _without_ Nix, so that
when we finally do, we can feel the difference.

There's many ways to go about this: everyone has their favorite code editor,
base Linux distribution (there's even a [NixOS](https://nixos.org/)
distribution, which I won't cover). Some folks like to develop on macOS first,
and _then_ build for Linux. ⌘ [Read more](https://fasterthanli.me/series/building-a-rust-service-with-nix/part-1) 2023-02-13T14:20:00Z **The bottom emoji breaks rust-analyzer**
Some bugs are merely fun. Others are simply delicious!

Today's pick is the latter.

## [Reproducing the issue, part 1](\#reproducing-the-issue-part-1) ⌘ [Read more](https://fasterthanli.me/articles/the-bottom-emoji-breaks-rust-analyzer) 2023-01-12T14:00:00Z **Day 18 (Advent of Code 2022)**
This time around, we're porting a solution from C++ to Rust and seeing how it
feels, how it performs, and what we can learn about both languages by doing that.

See [Day 17](part-17) for the rationale re: porting solutions rather than
writing my own from scratch. TL;DR is: it's better than nothing, and we can
still focus about learning Rust rather than spending entire days fighting
off-by-one errors. ⌘ [Read more](https://fasterthanli.me/series/advent-of-code-2022/part-18) 2023-01-12T13:00:00Z **Twitch fell behind**
So you want to do live streams. Are you sure? Okay. Let's talk about it.

## [Let's talk numbers](\#let-s-talk-numbers) ⌘ [Read more](https://fasterthanli.me/articles/twitch-fell-behind) 2023-01-11T15:00:00Z **Day 17 (Advent of Code 2022)**
Advent of Code gets harder and harder, and I'm not getting any smarter. Or any
more free time. So, in order to close out this series anyway, I'm going to try
and port other people's solutions from "language X" to Rust. That way, they
already figured out the hard stuff, and we can just focus on the Rust bits! ⌘ [Read more](https://fasterthanli.me/series/advent-of-code-2022/part-17) 2022-12-29T15:00:00Z **Day 16 (Advent of Code 2022)**
Let's tackle the [day 16 puzzle](https://adventofcode.com/2022/day/16)!

## [Parsing](\#parsing)

The input looks like this:

```
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
Valve BB has flow rate=13; tunnels lead to valves CC, AA
Valve CC has flow rate=2; tunnels lead to valves DD, BB
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
Valve EE has flow rate=3; tunnels lead to valves FF, DD
Valve FF has flow rate=0; tunnels lead to valves EE, GG
Valve GG ... ⌘ [Read more](https://fasterthanli.me/series/advent-of-code-2022/part-16) 2022-12-25T17:00:00Z **Day 15 (Advent of Code 2022)**
The [day 15 puzzle](https://adventofcode.com/2022/day/15) falls into the "math
puzzle" territory more than "let's learn something new about Rust", but since
several folks asked if I was going to continue... let's continue. ⌘ [Read more](https://fasterthanli.me/series/advent-of-code-2022/part-15) 2022-12-15T19:00:00Z **Day 14 (Advent of Code 2022)**
I like how the [day 14 puzzle](https://adventofcode.com/2022/day/14) sounds,
because I think it'll give me an opportunity to show off yet _another way_ to
have Rust embedded in a web page.

But first...

Let me guess: parsing? ⌘ [Read more](https://fasterthanli.me/series/advent-of-code-2022/part-14) 2022-12-14T20:30:00Z **Day 13 (Advent of Code 2022)**
The [day 13 puzzle](https://adventofcode.com/2022/day/13) needs a speech
therapist.

???

...because it has an awful lisp!! Ahhhahahahhhh

Are you ok? What is.. what is going on with you?

No but seriously we have what are ostensibly S-expressions, except they use
JSON-adjacent notation:

```
[1,1,3,1,1]
[1,1,5,1,1]

[[1],[2,3,4]]
[[1],4]

[9]
[[8,7,6]]

[[4,4],4,4]
[[4,4],4,4,4]

[7,7,7,7]
[7,7,7]

[]
[3]

[[[]]]
[[]]

[1,[2,[3,[4,[5,6,7]]]],8,9]
[1,[2,[3,[4,[5,6,0]]]],8,9]

``` ⌘ [Read more](https://fasterthanli.me/series/advent-of-code-2022/part-13) 2022-12-13T18:00:00Z **Day 12 (Advent of Code 2022)**
Alright! The [day 12 puzzle](https://adventofcode.com/2022/day/12) involves path
finding, and it seems like a good time to lean more heavily on the WASM embeds
I've set up for the previous parts.

Let's start by setting up the types we'll want!

## [Types and parsing](\#types-and-parsing) ⌘ [Read more](https://fasterthanli.me/series/advent-of-code-2022/part-12) 2022-12-12T18:10:00Z **Day 11 (Advent of Code 2022)**
It's a new day, it's a [new advent of code\
puzzle](https://adventofcode.com/2022/day/11).

In that one, we have to apparently cosplay as an IBM mainframe and just.. crunch
them numbers. This doesn't look fun, and I can't think of a clever twist to make
it fun, so let's try to make it short and sweet.

## [Parsing](\#parsing) ⌘ [Read more](https://fasterthanli.me/series/advent-of-code-2022/part-11) 2023-10-19T16:50:00Z **Just paying Figma $15/month because nothing else fucking works**
## [Entrée](\#entree)

My family wasn't poor by any stretch of the imagination, but I was raised to
avoid spending money whenever possible. ⌘ [Read more](https://fasterthanli.me/articles/just-paying-figma-15-dollars) 2024-03-02T18:00:00Z **Face cams: the missing guide**
I try to avoid doing "meta" / "behind the scenes" stuff, because I usually feel
like it has to be "earned". How many YouTube channels are channels about making
YouTube videos? Too many. ⌘ [Read more](https://fasterthanli.me/articles/face-cams-the-missing-guide) 2024-04-08T16:30:00Z **Begging EuroRust to acknowledge independent workers**
TL;DR I purchased individual tickets for EuroRust and added my VAT number, so
it could be a tax-deductible expense for me as an independent worker.

The organizers reached out asking me to buy business tickets instead. I'm asking
them to reconsider their policy.

## [What is an independent worker?](\#what-is-an-independent-worker) ⌘ [Read more](https://fasterthanli.me/articles/begging-eurorust-to-acknowledge-independent-workers)