Cadey is coffee
<Cadey> Hello! Thank you for visiting my website. You seem to be using an ad-blocker. I understand why you do this, but I'd really appreciate if it you would turn it off for my website. These ads help pay for running the website and are done by Ethical Ads. I do not receive detailed analytics on the ads and from what I understand neither does Ethical Ads. If you don't want to disable your ad blocker, please consider donating on Patreon or sending some extra cash to xeiaso.eth or 0xeA223Ca8968Ca59e0Bc79Ba331c2F6f636A3fB82. It helps fund the website's hosting bills and pay for the expensive technical editor that I use for my longer articles. Thanks and be well!

Site Update: Rewrite in Rust

Read time in minutes: 8

Hello there! You are reading this post thanks to a lot of effort, research and consultation that has resulted in a complete from-scratch rewrite of this website in Rust. The original implementation in Go is available here should anyone want to reference that for any reason.

If you find any issues with the RSS feed, Atom feed or JSONFeed, please let me know as soon as possible so I can fix them.

This website stands on the shoulder of giants. Here are just a few of those and how they add up into this whole package.


All of my posts are written in markdown. comrak is a markdown parser written by a friend of mine that is as fast and as correct as possible. comrak does the job of turning all of that markdown (over 150 files at the time of writing this post) into the HTML that you are reading right now. It also supports a lot of common markdown extensions, which I use heavily in my posts.


warp is the web framework I use for Rust. It gives users a set of filters that add up into entire web applications. For an example, see this example from its readme:

use warp::Filter;

async fn main() {
    // GET /hello/warp => 200 OK with body "Hello, warp!"
    let hello = warp::path!("hello" / String)
        .map(|name| format!("Hello, {}!", name));

        .run(([127, 0, 0, 1], 3030))

This can then be built up into something like this:

let site = index
    // ...

which is the actual routing setup for this website!


In the previous version of this site, I used Go's html/template. Rust does not have an equivalent of html/template in its standard library. After some research, I settled on ructe for the HTML templates. ructe works by preprocessing templates using a little domain-specific language that compiles down to Rust source code. This makes the templates become optimized with the rest of the program and enables my website to render most pages in less than 100 microseconds. Here is an example template (the one for /patrons):

@use patreon::Users;
@use super::{header_html, footer_html};

@(users: Users)

@:header_html(Some("Patrons"), None)


<p>These awesome people donate to me on <a href="">Patreon</a>.
If you would like to show up in this list, please donate to me on Patreon. This
is refreshed every time the site is deployed.</p>

        @for user in users {


The templates compile down to Rust, which lets me include other parts of the program into the templates. Here I use that to take a list of users from the incredibly hacky Patreon API client I wrote for this website and iterate over it, making a list of every patron by name.

Build Process

As a nice side effect of this rewrite, my website is now completely built using Nix. This allows the website to be built reproducibly, as well as a full development environment setup for free for anyone that checks out the repo and runs nix-shell. Check out naersk for the secret sauce that enables my docker image build. See this blogpost for more information about this build process (though my site uses GitHub Actions instead of Drone).

jsonfeed Go package

I used to have a JSONFeed package publicly visible at the go import path As far as I know I'm the only person who ended up using it; but in case there are any private repos that I don't know about depending on it, I have made the jsonfeed package available at its old location as well as its source code here. You may have to update your go.mod file to import instead of If something ends up going wrong as a result of this, please file a GitHub issue here and I can attempt to assist further.

go_vanity crate

I have written a small go vanity import crate and exposed it in my Git repo. If you want to use it, add it to your Cargo.toml like this:

go_vanity = { git = "", branch = "master" }

You can then use it from any warp application by calling go_vanity::github or go_vanity::gitea like this:

let go_vanity_jsonfeed = warp::path("jsonfeed")
    .and(warp::any().map(move || ""))
    .and(warp::any().map(move || ""))

I plan to add full documentation to this crate soon as well as release it properly on

patreon crate

I have also written a small Patreon API client and made it available in my Git repo. If you want to use it, add it to your Cargo.toml like this:

patreon = { git = "", branch = "master" }

This client is incredibly limited and only supports the minimum parts of the Patreon API that are required for my website to function. Patreon has also apparently started to phase out support for its API anyways, so I don't know how long this will be useful.

But this is there should you need it!

Dhall Kubernetes Manifest

I also took the time to port the kubernetes manifest to Dhall. This allows me to have a type-safe kubernetes manifest that will correctly have all of the secrets injected for me from the environment of the deploy script.

These are the biggest giants that my website now sits on. The code for this rewrite is still a bit messy. I'm working on making it better, but my goal is to have this website's code shine as an example of how to best write this kind of website in Rust. Check out the code here.

This article was posted on M07 16 2020. Facts and circumstances may have changed since publication. Please contact me before jumping to conclusions if something seems wrong or unclear.

Series: site-update

Tags: rust

This post was not WebMentioned yet. You could be the first!

The art for Mara was drawn by Selicre.

The art for Cadey was drawn by ArtZora Studios.

Some of the art for Aoi was drawn by @Sandra_Thomas01.