Articles tagged #rust

Day 1 (Advent of Code 2022)

Two years ago, I did part of Advent of Code 2020 using the Rust language. It was a lot of fun, so let’s try it again!

The problem statement

Our input looks something like this:

1000 2000 3000 4000 5000 6000 7000 8000 9000 10000

Each group of lines separated by an empty line is a list of food items an elf is carrying: each line corresponds to the number of calories in that food.

Advent of Code 2022

Let’s use the Advent of Code 2022, a series of programming challenges of increasing difficulty, to learn more about the Rust programming language.

Async fn in trait, for real this time

async_trait’s one weird type ascription trick

Now that I got the Log in with GitHub feature working, let’s explore what this would’ve looked like with the async_trait crate.

First up, the trait definition:

/// Something that can refresh credentials #[async_trait::async_trait] pub trait CredentialsRefresher { async fn refresh(&self, creds: &FutileCredentials) -> eyre::Result<FutileCredentials>; }

Implementing "Log in with GitHub"

Because I started accepting donations via GitHub Sponsors, and because donating at the “Silver” tier or above gives you advance access to articles and your name in the credits, I need to interface with the GitHub API the same way I do the Patreon API.

Because I’d rather rely on third-party identity providers than provide my own sign up / log in / password forgotten / 2FA flow, user identifiers on my website are simply {provider}:{provider_specific_user_id}:

Trying to use nix

Now that my website is deployed as a container image, I wanted to give nix a try. I’m still doing it the old-fashioned way right now: with a Dockerfile, running cargo in a “builder” image, copying stuff out of there into a slimmer image (that still has an Ubuntu base, even though distroless images are a thing now).

But why?

I was mostly interested in nix because some parts of my website have pretty big native dependencies. futile itself mostly relies on sqlite3 and some JS engine (used to be quickjs, currently duktape because MSVC Windows builds). But the asset processing pipeline, salvage (which I’d like to integrate with futile at some point) has a bunch more!

Deploying at the edge

Disclaimer:

Although I no longer work for the company my website is hosted on, and this article is written in way that mentions neither my previous or current hosting provider: at the time of this writing, I don’t pay for hosting.

One thing I didn’t really announce (because I wanted to make sure it worked before I did), is that I’ve migrated my website over completely from a CDN (Content Delivery Network) to an ADN (Application Delivery Network), and that required some architectural changes.

Async fn in trait... not

Async fn in trait… not

I was planning on showing the in-progress async_fn_in_trait feature in the context of my website, but it turns out, I can’t!

My website uses two databases: one local SQLite database for content, and a shared Postgres database for user credentials, preferences etc. Migrations are run on startup, and each migration implements one of the following traits:

Migrating from warp to axum

Falling out of love with warp

Back when I wrote this codebase, warp was the best / only alternative for something relatively high-level on top of hyper.

I was never super fond of warp’s model — it’s a fine crate, just not for me.

The way routing works is essentially building a type that gets larger and larger. One route might look like:

let bye = warp::path("bye") .and(warp::path::param()) .map(|name: String| format!("Good bye, {}!", name));

Go back to the homepage.