<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ben Lovy</title>
    <description>The latest articles on Forem by Ben Lovy (@deciduously).</description>
    <link>https://forem.com/deciduously</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F63000%2F2c770bec-a282-4dce-a8a1-9de749786416.jpg</url>
      <title>Forem: Ben Lovy</title>
      <link>https://forem.com/deciduously</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/deciduously"/>
    <language>en</language>
    <item>
      <title>Oops, I Did It Again...I Made A Rust Web API And It Was Not That Difficult</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Sun, 21 Nov 2021 23:02:27 +0000</pubDate>
      <link>https://forem.com/deciduously/oops-i-did-it-againi-made-a-rust-web-api-and-it-was-not-that-difficult-3kk8</link>
      <guid>https://forem.com/deciduously/oops-i-did-it-againi-made-a-rust-web-api-and-it-was-not-that-difficult-3kk8</guid>
      <description>&lt;p&gt;Over two years ago (oof), I posted &lt;a href="https://dev.to/deciduously/skip-the-framework-build-a-simple-rust-api-with-hyper-4jf5"&gt;a walkthrough&lt;/a&gt; of my Rust implementation of &lt;a href="https://github.com/gypsydave5/todo-mvp"&gt;todo-mvp&lt;/a&gt; by &lt;a class="mentioned-user" href="https://dev.to/gypsydave5"&gt;@gypsydave5&lt;/a&gt; demonstrating how to build a simple Rust API without a framework.  The core functionality was built using &lt;a href="https://hyper.rs"&gt;hyper&lt;/a&gt;, a lower-level HTTP library instead of a full-blown framework.&lt;/p&gt;

&lt;p&gt;It turns out I wrote that post about six months too early.  I published it in May 2019, and in November, Rust released 1.39.0 containing &lt;code&gt;async/await&lt;/code&gt; syntax.  Womp womp.&lt;/p&gt;

&lt;p&gt;My intent here was to simply upgrade the existing application to use the new syntax where applicable and call it a day.  But, you know that thing that happens when you go back and review code you wrote years ago?  Yeah, that thing happened.  We're starting from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's New
&lt;/h2&gt;

&lt;p&gt;Our result functions almost identically to the implementation in the previous post, so some of this code will look very similar. Here's a quick overview of the new stuff you'll find in this post not present in the previous version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.rs/anyhow/1.0.47/anyhow/"&gt;anyhow&lt;/a&gt; - Error handling for humans.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rust-lang.github.io/async-book/"&gt;async/await&lt;/a&gt; - New syntax for expressing asynchronous computation - like a webserver!&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://doc.rust-lang.org/std/panic/fn.catch_unwind.html"&gt;catch_unwind&lt;/a&gt; - A panicking task shouldn't crash your whole server!  Gracefully catch the panic and keep on servin'.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.rs/flate2/1.0.22/flate2/"&gt;compression&lt;/a&gt; - Every response will be DEFLATE compressed, simply because we can.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html"&gt;Rust 2021&lt;/a&gt; - &lt;em&gt;the future of Rust&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;state management - Instead of a global variable, we'll use &lt;a href="https://docs.rs/hyper/0.14.15/hyper/struct.Request.html#method.extensions"&gt;protocol extensions&lt;/a&gt; to access the app state.&lt;/li&gt;
&lt;li&gt;tracing - The &lt;a href="https://docs.rs/log/0.4.14/log/"&gt;&lt;code&gt;log&lt;/code&gt;&lt;/a&gt; crate is old news. All the cool kids use &lt;a href="https://docs.rs/tracing/0.1.29/tracing/"&gt;&lt;code&gt;tracing&lt;/code&gt;&lt;/a&gt; now.&lt;/li&gt;
&lt;li&gt;unit testing - We didn't have &lt;em&gt;any&lt;/em&gt; last time - tsk tsk!  Learn how to write &lt;a href="https://docs.rs/tokio/1.14.0/tokio/attr.test.html"&gt;async unit tests&lt;/a&gt; for your handlers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;To follow along, you'll need a stable Rust toolchain.  See the &lt;a href="https://www.rust-lang.org/tools/install"&gt;install page&lt;/a&gt; for instructions to install &lt;code&gt;rustup&lt;/code&gt; for your platform.  You should prefer this method to your distribution's package manager.  If you're a NixOS freak, I recommend &lt;a href="https://github.com/nix-community/fenix"&gt;fenix&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once your environment is set up, start a new project and make sure you can build it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cargo new simple-todo
   Created binary (application) `simple-todo` package
$ cd simple-todo
$ cargo run
   Compiling simple-todo v0.1.0 (/home/deciduously/code/simple-todo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.19s
     Running `target/debug/simple-todo
Hello, world!

$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open up your &lt;code&gt;Cargo.toml&lt;/code&gt; and make it look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[package]&lt;/span&gt;
&lt;span class="py"&gt;authors&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Cool Person &amp;lt;cool.person@yourcoolsite.neato&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;edition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2021"&lt;/span&gt;
&lt;span class="py"&gt;rust-version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.56"&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"simple-todo"&lt;/span&gt;
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1.0"&lt;/span&gt;

&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;anyhow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;
&lt;span class="py"&gt;backtrace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.3"&lt;/span&gt;
&lt;span class="nn"&gt;clap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"3.0.0-beta.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["color"]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;flate2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;
&lt;span class="py"&gt;futures&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.3"&lt;/span&gt;
&lt;span class="nn"&gt;hyper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.14"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["full"]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;lazy_static&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.4"&lt;/span&gt;
&lt;span class="nn"&gt;serde&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["derive"]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;serde_json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;
&lt;span class="py"&gt;tracing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1"&lt;/span&gt;
&lt;span class="nn"&gt;tracing-subscriber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["env-filter"]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;tera&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;
&lt;span class="nn"&gt;tokio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["full"]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nn"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"serde"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"v4"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nn"&gt;[dev-dependencies]&lt;/span&gt;

&lt;span class="py"&gt;pretty_assertions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.7"&lt;/span&gt;
&lt;span class="py"&gt;select&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.5"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are some new elements here already, up in the package section.  &lt;a href="https://doc.rust-lang.org/edition-guide/rust-2021/index.html"&gt;Rust 2021&lt;/a&gt; was recently released, and along with it, the &lt;code&gt;rust-version&lt;/code&gt; metadata key, allowing you to specify the Minimum Supported Rust Version (MSRV) directly in the package.&lt;/p&gt;

&lt;p&gt;This post is only concerned with Rust and will use assets identical to the last post.  Create a folder called &lt;code&gt;templates&lt;/code&gt; at the project's top-level, and place &lt;a href="https://github.com/gypsydave5/todo-mvp/blob/master/todos/rust/templates/index.html"&gt;this index.html&lt;/a&gt; inside.  You will also need to create a directory at &lt;code&gt;src/resource&lt;/code&gt; and fill it with &lt;a href="https://github.com/gypsydave5/todo-mvp/tree/master/todos/rust/src/resource"&gt;these files&lt;/a&gt;.  There is a stylesheet and a handful of SVG files.  Your structure should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree
.
├── Cargo.lock
├── Cargo.toml
├── src
│  ├── main.rs
│  └── resource
│     ├── check.svg
│     ├── plus.svg
│     ├── tick.png
│     ├── todo.css
│     ├── trashcan.svg
│     └── x.svg
└── templates
   └── index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good to go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Entrypoint
&lt;/h2&gt;

&lt;p&gt;This whole app will live in &lt;code&gt;src/main.rs&lt;/code&gt;.  Start off by adding the imports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anyhow&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;backtrace&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Backtrace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;clap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Parser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;flate2&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;write&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ZlibEncoder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Compression&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;futures&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;future&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FutureExt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;lazy_static&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;lazy_static&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RefCell&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AssertUnwindSafe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PathBuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RwLock&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;tera&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Tera&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's nice to allow the user to specify where to run their app.  The &lt;code&gt;clap&lt;/code&gt; library provides a convenient way to specify command-line arguments in a struct.  This feature is still in beta but will stabilize soon.  We can create a struct and use the &lt;code&gt;Parser&lt;/code&gt; feature to generate the options:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Parser)]&lt;/span&gt;
&lt;span class="nd"&gt;#[clap(version&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;concat&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="nd"&gt;(env&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="nd"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CARGO_PKG_VERSION"&lt;/span&gt;&lt;span class="nd"&gt;)),&lt;/span&gt; &lt;span class="nd"&gt;about&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Serve a TODO list application."&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Args&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[clap(&lt;/span&gt;
        &lt;span class="nd"&gt;short,&lt;/span&gt;
        &lt;span class="nd"&gt;long,&lt;/span&gt;
        &lt;span class="nd"&gt;about&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Address to bind the server to."&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt;
        &lt;span class="nd"&gt;env,&lt;/span&gt;
        &lt;span class="nd"&gt;default_value&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;
    &lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[clap(short,&lt;/span&gt; &lt;span class="nd"&gt;long,&lt;/span&gt; &lt;span class="nd"&gt;about&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Port to listen on."&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;env,&lt;/span&gt; &lt;span class="nd"&gt;default_value&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"3000"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When run without any arguments, the server will bind to &lt;code&gt;0.0.0.0:3000&lt;/code&gt;, a reasonable default.  This allows users to either use the &lt;code&gt;ADDRESS&lt;/code&gt; and &lt;code&gt;PORT&lt;/code&gt; environment variables or &lt;code&gt;-a/--address&lt;/code&gt; and &lt;code&gt;-p/--port&lt;/code&gt; command-line arguments.  It also provides a nice &lt;code&gt;--help&lt;/code&gt; implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;simple-todo 0.1.0

Serve a TODO list application.

USAGE:
    todo-mvp-rust [OPTIONS]

OPTIONS:
    -a, --address &amp;lt;ADDRESS&amp;gt;    Address to bind the server to. [env: ADDRESS=] [default: 0.0.0.0]
    -h, --help                 Print help information
    -p, --port &amp;lt;PORT&amp;gt;          Port to listen on. [env: PORT=] [default: 3000]
    -V, --version              Print version information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;main()&lt;/code&gt; function will just parse these arguments and pass them off to our app routine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Args&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've brought &lt;a href="https://github.com/dtolnay/anyhow"&gt;&lt;code&gt;anyhow::Result&lt;/code&gt;&lt;/a&gt; into scope, making error handling super easy to use.  We don't need to specify all our &lt;code&gt;Error&lt;/code&gt; types. It can automatically convert any errors that implement &lt;code&gt;std::error::Error&lt;/code&gt;, which should be all of them.  If an error propagates all the way up to &lt;code&gt;main()&lt;/code&gt;, we'll get all the info it's captured printed to stdout.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;app()&lt;/code&gt; function is our &lt;em&gt;real&lt;/em&gt; entrypoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;tracing_subscriber&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;SocketAddr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="py"&gt;.address&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="py"&gt;.port&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Todos&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;RwLock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function is tagged with &lt;code&gt;#[tokio::main]&lt;/code&gt;, meaning it will execute an async runtime.  All the functions we're using now can be marked &lt;code&gt;async&lt;/code&gt;, meaning we can &lt;code&gt;await&lt;/code&gt; the result.  Under the hood, Rust converts these functions into constructs called Futures, and in the previous iteration we built these manually.  Futures can either be &lt;code&gt;Ready&lt;/code&gt; or &lt;code&gt;Waiting&lt;/code&gt;.  You can call the &lt;code&gt;poll()&lt;/code&gt; method on a future, which just asks: "are you ready, or are you waiting?" If the future is ready to resolve, it will pass up the response, and if it's waiting, it will just respond with &lt;code&gt;Pending&lt;/code&gt;.  It can return a &lt;code&gt;wake()&lt;/code&gt; callback, letting the caller know there's a value.  When &lt;code&gt;wake&lt;/code&gt; is executed, the caller will know to &lt;code&gt;poll()&lt;/code&gt; this future again, resolving it to a value.&lt;/p&gt;

&lt;p&gt;This all involved a lot of ceremony.  This &lt;code&gt;async/.await&lt;/code&gt; syntax abstracts these concepts for us.  We just write functions like normal, except we mark them &lt;code&gt;async&lt;/code&gt;, and when control flow hits a point where we need to wait for a result to resolve, we can use &lt;code&gt;await&lt;/code&gt;.  If these are used within an executor like &lt;code&gt;#[tokio::main]&lt;/code&gt;, the runtime will cover all the details.  Instead of blocking control flow, each of these &lt;code&gt;await&lt;/code&gt; points will yield to other running tasks on this executor until the underlying &lt;code&gt;Future&lt;/code&gt; returns from a &lt;code&gt;poll()&lt;/code&gt; request as &lt;code&gt;Ready&amp;lt;T&amp;gt;&lt;/code&gt;.  This makes our types easier to reason about and our code much more straightforward to write.&lt;/p&gt;

&lt;p&gt;This top-level function reads our argument struct to build the &lt;code&gt;SocketAddr&lt;/code&gt; to bind to, starts up the logging system with &lt;a href="https://docs.rs/tracing-subscriber/0.3.2/tracing_subscriber/index.html"&gt;&lt;code&gt;tracing_subscriber&lt;/code&gt;&lt;/a&gt;, and builds our state management.  Then, we call the &lt;code&gt;serve()&lt;/code&gt; async function and &lt;code&gt;await&lt;/code&gt; on the result.  This executor will run forever until the user kills the process and can handle multiple concurrent connections for us seamlessly.&lt;/p&gt;

&lt;p&gt;For a sneak preview, this is the signature of &lt;code&gt;serve()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;serve&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SocketAddr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It requires we pass an address, then an &lt;code&gt;Arc&amp;lt;C&amp;gt;&lt;/code&gt;.  That &lt;code&gt;C&lt;/code&gt; type is our app state, and for this to work, it must implement the &lt;a href="https://doc.rust-lang.org/nomicon/send-and-sync.html"&gt;&lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt;&lt;/a&gt; traits.  &lt;code&gt;Send&lt;/code&gt; means the value can be sent to another thread, and &lt;code&gt;Sync&lt;/code&gt; means it can be shared between threads simultaneously.&lt;/p&gt;

&lt;p&gt;In our case, we don't need to think too hard about this.  We're using an &lt;code&gt;Arc&amp;lt;RwLock&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; to allow mutation to provide a type that can be accessed from multiple tasks and safely mutated as needed.  As long as each task grabs the proper lock, we don't need to worry about concurrent tass clobbering each other.  Only one task will be able to write to this type at a time, so every new reader will always have the correct data.&lt;/p&gt;

&lt;p&gt;Finally, we need to add a handler with type &lt;code&gt;H&lt;/code&gt;.  These types start to peel back a little of what &lt;code&gt;async&lt;/code&gt; is doing for us.  Stripping out the &lt;code&gt;Send + Sync&lt;/code&gt; trait bounds, this function satisfies the trait bound &lt;code&gt;Fn(Request) -&amp;gt; Future&amp;lt;Output = Response&amp;gt;&lt;/code&gt;.  Because we're in an async environment, we can just write &lt;code&gt;async fn handle(request: Request) -&amp;gt; Response&lt;/code&gt; - it's an asynchronous function from a request to a response.  Sounds like a web server to me!  Using Rust's &lt;code&gt;async/.await&lt;/code&gt;, we get to simply write what we mean.&lt;/p&gt;

&lt;p&gt;We'll come back to the handler shortly - first, we have a little bit of setup to take care of.&lt;/p&gt;

&lt;h2&gt;
  
  
  Templates
&lt;/h2&gt;

&lt;p&gt;This application only consists of a single page that will be refreshed whenever the state changes.  We placed markup at &lt;code&gt;templates/index.html&lt;/code&gt;, an HTML file using &lt;a href="https://jinja.palletsprojects.com/en/3.0.x/"&gt;Jinja&lt;/a&gt;-style templating. We'll use &lt;a href="https://tera.netlify.app/"&gt;&lt;code&gt;Tera&lt;/code&gt;&lt;/a&gt; to handle this in Rust.&lt;/p&gt;

&lt;p&gt;The templates need to be compiled before use, but this only needs to happen once.  We can use &lt;a href="https://github.com/rust-lang-nursery/lazy-static.rs"&gt;&lt;code&gt;lazy_static&lt;/code&gt;&lt;/a&gt; to ensure this compilation happens the first time the templates are accessed, and then reuse the compiled result for all subsequent access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;lazy_static!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;TERA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Tera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nn"&gt;Tera&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"templates/**/*"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unable to parse templates: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can use the &lt;code&gt;TERA&lt;/code&gt; global.  If Tera could not compile the templates for any reason, the process will exit here and display the error.  Our server only works if this step completes successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  State
&lt;/h2&gt;

&lt;p&gt;Next, we need to define the app state.  The application revolves around a &lt;code&gt;Todo&lt;/code&gt; type with a name, an ID, and a boolean tracking whether it's been completed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Serialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_v4&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We just need to provide a string name, like &lt;code&gt;Todos::new("Task")&lt;/code&gt;, and this type will generate a new unique ID and set it to incomplete.&lt;/p&gt;

&lt;p&gt;Storage is pretty simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Default)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;Todos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need methods to add new todos, remove existing todos, and toggle the &lt;code&gt;done&lt;/code&gt; boolean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Todos&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="nf"&gt;.remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nb"&gt;None&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="py"&gt;.done&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="py"&gt;.done&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notably, we don't have to write any unique code to make this thread safe.  We can write it exactly as we would in a single-threaded, synchronous context and trust that Rust won't let us mutably access this unsafely.  This is what got instantiated up in &lt;code&gt;app()&lt;/code&gt; with these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Todos&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;RwLock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wrapping this all in an &lt;code&gt;Arc&lt;/code&gt; means that any task accessing this value can get their own reference to it, and the &lt;code&gt;RwLock&lt;/code&gt; will allow multiple concurrent readers &lt;em&gt;or&lt;/em&gt; exactly one writer at a time.  When the lock is released, the next waiting task will be able to take control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handler
&lt;/h2&gt;

&lt;p&gt;We're finally ready to take a look at the handler.  Per the signature up above, we know we need a function with the following signature: &lt;code&gt;async fn handle(request: Request) -&amp;gt; Response&lt;/code&gt;.  Each time our web server receives an HTTP request, it will call this function to produce a Response to send back.  First, add type aliases for the request and response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;hyper&lt;/code&gt; crate defines all the types we need.  In both cases, the request and response will carry a &lt;a href="https://docs.rs/hyper/0.14.15/hyper/body/struct.Body.html"&gt;&lt;code&gt;hyper::Body&lt;/code&gt;&lt;/a&gt;.  Every single handler will use this type signature, so defining these aliases saves us a lot of typing.&lt;/p&gt;

&lt;p&gt;The request contains information about how it was sent.  We can use Rust's &lt;code&gt;match&lt;/code&gt; construct to read both the incoming URI and HTTP method to correctly dispatch a response. Here's the whole body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// pattern match for both the method and the path of the request&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.uri&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.path&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// GET handlers&lt;/span&gt;
        &lt;span class="c1"&gt;// Index page handler&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/index.html"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// Style handler&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/static/todo.css"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;stylesheet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// Image handler&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// POST handlers&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/done"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;toggle_todo_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/not-done"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;toggle_todo_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/delete"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;remove_todo_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;add_todo_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// Anything else handler&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;four_oh_four&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each match arm will match with a specific combination of HTTP verb and path.  For example, &lt;code&gt;GET /static/todo.css&lt;/code&gt; will properly dispatch the &lt;code&gt;stylesheet()&lt;/code&gt; handler, but &lt;code&gt;POST /static/todo.css&lt;/code&gt; is not supported and will fall through to &lt;code&gt;four_oh_four()&lt;/code&gt;.  Each of these handlers is itself an &lt;code&gt;async&lt;/code&gt; function, but we don't want to return up to the caller until they've been polled as &lt;code&gt;ready&lt;/code&gt;, and return an actual &lt;code&gt;Response&lt;/code&gt;.  Remember, Rust is doing this for us - when we write &lt;code&gt;async fn() -&amp;gt; Response&lt;/code&gt;, we actually get a &lt;code&gt;Fn() -&amp;gt; impl Future&amp;lt;Output = Response&amp;gt;&lt;/code&gt;.  We can't use that return type until the future resolves! That's what the &lt;code&gt;.await&lt;/code&gt; syntax signifies.  Once the future is ready, we'll use the resulting &lt;code&gt;Response&lt;/code&gt; output but not before.&lt;/p&gt;

&lt;p&gt;The most straightforward handler is &lt;code&gt;four_oh_four()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;four_oh_four&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;html_str_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;h1&amp;gt;NOT FOUND!&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NOT_FOUND&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This response doesn't depend on the request - the request didn't make any sense to us, after all! There's no input parameter, but like all handlers, it produces a &lt;code&gt;Response&lt;/code&gt;.  Because all of our routes need to build responses, I pulled this logic out into a series of building-block functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Response Builders
&lt;/h2&gt;

&lt;p&gt;Most of our &lt;code&gt;Response&lt;/code&gt; building shares a lot of logic. We usually send back some form of string, and we want to attach a content type and a status code.  Because we care about our user's bandwidth usage, we also want to compress our responses, ensuring as little as possible is sent over the wire.  The most common case is a successful response containing HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;ok_html_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;html_str_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This, in turn, calls the HTML string handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;html_str_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;string_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;four_oh_four()&lt;/code&gt; handler used this directly to include a different status code.  Ultimately, though, it's all just strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;string_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;bytes_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="nf"&gt;.as_bytes&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;ok_string_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;string_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These helpers allow for other content types as long as the body is still passed as a string.  This covers all the body types we need for this application.  At the bottom, we get to &lt;code&gt;bytes_handler&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;bytes_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;encoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ZlibEncoder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;Compression&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;encoder&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;compressed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;encoder&lt;/span&gt;&lt;span class="nf"&gt;.finish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;header&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CONTENT_TYPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;header&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CONTENT_ENCODING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"deflate"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compressed&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function takes a byte slice (&lt;code&gt;&amp;amp;[u8]&lt;/code&gt;), and &lt;code&gt;DEFLATE&lt;/code&gt; compresses it.  It adds the proper &lt;code&gt;Content-Encoding&lt;/code&gt; header so that any connected client can uncompress the payload before presenting it back to the user.  This is a rapid operation, and the smaller your payloads, the better.  Every response that contains a body will eventually pass through this function before bubbling back up to the top-level &lt;code&gt;handle()&lt;/code&gt; function and back to the client.&lt;/p&gt;

&lt;p&gt;There's one more response type for this application, and this doesn't use a body at all.  Whenever our app state changes, we will use the &lt;code&gt;301&lt;/code&gt; HTTP status code to trigger the client to redirect back to the index.  Every time the index is rendered, it reads the current app state, meaning any mutation executed in the handler will be automatically reflected on the refresh.  This function calls &lt;code&gt;Response::builder()&lt;/code&gt; directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;redirect_home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SEE_OTHER&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;header&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LOCATION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Main page
&lt;/h2&gt;

&lt;p&gt;Now, we have everything we need to render the app.  Our index function is the first handler that requires state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Set up index page template rendering context&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;tera_ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tera&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;todos_ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RwLock&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Todos&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.extensions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;todos_ctx&lt;/span&gt;&lt;span class="nf"&gt;.read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="nf"&gt;.todos&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;tera_ctx&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"todos"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;tera_ctx&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"todosLen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TERA&lt;/span&gt;&lt;span class="nf"&gt;.render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"index.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;tera_ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;ok_html_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the previous iteration of this app, the &lt;code&gt;Todos&lt;/code&gt; struct was instantiated alongside our &lt;code&gt;TERA&lt;/code&gt; templates in a global static variable.  A better solution is to thread it through to our handler using the &lt;code&gt;Request&lt;/code&gt; itself. We'll look at the implementation lower down, but by the time we get here, there's a fresh &lt;code&gt;Arc&lt;/code&gt; containing the context ready to be read.  We can use &lt;code&gt;request.extensions().get()&lt;/code&gt; and &lt;code&gt;Arc::clone()&lt;/code&gt; to grab our very own reference to the app state to use for building this response.  The request extensions use the type of what's stored for access, so we need to explicitly add the type of &lt;code&gt;todos_ctx&lt;/code&gt; to indicate what we're looking for.&lt;/p&gt;

&lt;p&gt;Next, we build the index page using the current state of the app.  This handler won't perform any mutation, so we can use &lt;code&gt;todos_ctx.read()&lt;/code&gt;.  By introducing a child scope, we ensure our read lock gets dropped when we're done with it, allowing any writers waiting for access to grab their own locks.  If we needed to wait, no problem! We're in an &lt;code&gt;async&lt;/code&gt; function, the caller can poll us any time, and we'll just return &lt;code&gt;Pending&lt;/code&gt; until we're ready to go.  Nice and neat.&lt;/p&gt;

&lt;p&gt;Once we've received our handle to the app state, we can pass it through to Tera.  &lt;code&gt;TERA.render()&lt;/code&gt; will return an HTML string with all template values resolved using our app state.  Then, we can use our trusty &lt;code&gt;ok_html_handler()&lt;/code&gt; response builder to tag it with a proper content type and status code and compress the result before returning to the caller.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;index.html&lt;/code&gt; template will request a style sheet when it loads from &lt;code&gt;/static/todo.css&lt;/code&gt;. That's a pretty simple handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;stylesheet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;include_str!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"resource/todo.css"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;ok_string_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"text/css"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;include_str!()&lt;/code&gt; macro actually bundles the string content directly in your compiled binary.  These files need to be present at compile-time but do not need to be distributed in production.  The compiled binary already includes everything it needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  SVG
&lt;/h2&gt;

&lt;p&gt;All the image assets in this application are SVG, which is represented as XML.  This means we just need to read these strings and pass the proper content-type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path_str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;path_buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PathBuf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path_str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path_buf&lt;/span&gt;&lt;span class="nf"&gt;.file_name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;path_buf&lt;/span&gt;&lt;span class="nf"&gt;.extension&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="nf"&gt;.to_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="nb"&gt;None&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;four_oh_four&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"svg"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// build the response&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s"&gt;"check.svg"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;include_str!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"resource/check.svg"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s"&gt;"plus.svg"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;include_str!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"resource/plus.svg"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s"&gt;"trashcan.svg"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;include_str!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"resource/trashcan.svg"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s"&gt;"x.svg"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;include_str!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"resource/x.svg"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="nf"&gt;ok_string_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"image/svg+xml"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;four_oh_four&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I just used a catch-all - any GET request that's not for the index or the stylesheet is assumed to be for an image.  At the top, there's a little extra logic to make sure we're looking for an image file. If there's no extension, i.e. &lt;code&gt;/nonsense&lt;/code&gt;, this handler will dispatch a &lt;code&gt;four_oh_four()&lt;/code&gt;. Otherwise, we press forward and try to find the actual SVG file.  If we succeed, we just pass the string back, and if not, we also &lt;code&gt;four_oh_four()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Handlers
&lt;/h2&gt;

&lt;p&gt;The remaining handlers are involved with mutating the state.  All of them will pass a request body with an item.  For a new todo, it will be &lt;code&gt;item=Task&lt;/code&gt;, and for toggling or removing, it will hold the id: &lt;code&gt;item=e2104f6a-624d-498f-a553-29e559e78d33&lt;/code&gt;.  In either case, we just need to extract the value after the equals sign:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;extract_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.into_body&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bytes_buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;to_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;str_body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_buf&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str_body&lt;/span&gt;&lt;span class="nf"&gt;.split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'='&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.to_owned&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The body may come in chunks, so we use &lt;code&gt;hyper::body::to_bytes()&lt;/code&gt; to produce a single &lt;code&gt;Bytes&lt;/code&gt; value with everything concatenated.  We can then convert the bytes to a UTF-8 string and split on the &lt;code&gt;=&lt;/code&gt; to grab the actual payload.  All of our state mutation handlers call this function on the incoming request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add_todo_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;todos_ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RwLock&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Todos&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.extensions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;todos_ctx&lt;/span&gt;&lt;span class="nf"&gt;.write&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;redirect_home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;remove_todo_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;todos_ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RwLock&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Todos&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.extensions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;todos_ctx&lt;/span&gt;&lt;span class="nf"&gt;.write&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;parse_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;redirect_home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;toggle_todo_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;todos_ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RwLock&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Todos&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.extensions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;todos_ctx&lt;/span&gt;&lt;span class="nf"&gt;.write&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;parse_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;redirect_home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each handler grabs its own unique reference to the app state, then extracts the payload.  Like we did in &lt;code&gt;index()&lt;/code&gt;, we open a new scope to interact with the &lt;code&gt;RwLock&lt;/code&gt; mutex, and in this case, we use &lt;code&gt;todos_ctx.write()&lt;/code&gt; to request a mutable lock.  This blocks all other tasks until the mutation is complete.  Then, we just &lt;code&gt;redirect_home()&lt;/code&gt;.  This prompts the client to send a &lt;code&gt;GET /&lt;/code&gt; request, which leads our to-level handler to call &lt;code&gt;index()&lt;/code&gt;, which reads the newly-mutated app state to build the page.&lt;/p&gt;

&lt;p&gt;Groovy! That's a full-fledged TODO app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serve
&lt;/h2&gt;

&lt;p&gt;There's one missing piece.  We defined our &lt;code&gt;handle()&lt;/code&gt; function, but we haven't talked about &lt;code&gt;serve()&lt;/code&gt; beyond the type signature.  This one is pretty beefy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;serve&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SocketAddr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a task local that will store the panic message and backtrace if a panic occurs.&lt;/span&gt;
    &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;task_local!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;PANIC_MESSAGE_AND_BACKTRACE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RefCell&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Backtrace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;where&lt;/span&gt;
        &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.uri&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.path_and_query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.path&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_owned&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;info!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.extensions_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;AssertUnwindSafe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.catch_unwind&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;time&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;SystemTime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or_else&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PANIC_MESSAGE_AND_BACKTRACE&lt;/span&gt;&lt;span class="nf"&gt;.with&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="nf"&gt;.borrow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backtrace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;error!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;backtrace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;backtrace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s"&gt;"500"&lt;/span&gt;
                &lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backtrace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;.body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;info!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Response generated in {}μs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="nf"&gt;.elapsed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or_default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_micros&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Install a panic hook that will record the panic message and backtrace if a panic occurs.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;hook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;take_hook&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set_hook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;panic_info&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;panic_info&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;Backtrace&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;PANIC_MESSAGE_AND_BACKTRACE&lt;/span&gt;&lt;span class="nf"&gt;.with&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="nf"&gt;.borrow_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}));&lt;/span&gt;
    &lt;span class="c1"&gt;// Wrap the request handler and context with Arc to allow sharing a reference to it with each task.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;service&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;make_service_fn&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;service&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;service_fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;PANIC_MESSAGE_AND_BACKTRACE&lt;/span&gt;&lt;span class="nf"&gt;.scope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;RefCell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="p"&gt;}))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;server&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;try_bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;info!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🚀 serving at {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="nf"&gt;.serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set_hook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I know, I know. There's a lot here.  The meat of this function happens right at the end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;server&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;try_bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;info!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🚀 serving at {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="nf"&gt;.serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We build a &lt;code&gt;hyper::Server&lt;/code&gt;, bind it to the address we constructed from the &lt;code&gt;Args&lt;/code&gt; struct, and serve this &lt;code&gt;service&lt;/code&gt; thing. The &lt;code&gt;service&lt;/code&gt; is built right above that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;service&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;make_service_fn&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Infallible&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;service&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;service_fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;PANIC_MESSAGE_AND_BACKTRACE&lt;/span&gt;&lt;span class="nf"&gt;.scope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;RefCell&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also wrap the handler function in an &lt;code&gt;Arc&lt;/code&gt;.  Our context is already wrapped, so we clone both to get a local reference within this closure.  This allows the executor to spin up multiple concurrent versions of our handler service that all have access to the same state and logic.&lt;/p&gt;

&lt;p&gt;The beefy stuff happens in this &lt;code&gt;service()&lt;/code&gt; closure above.  This is where we take an incoming request and match it up with our handler and context.  A new instance is executed for each incoming request, and all this ceremony allows this to happen without interfering with other simultaneous requests.&lt;/p&gt;

&lt;p&gt;For one, this is where we add our context to the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.extensions_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we call &lt;code&gt;request.extensions().get()&lt;/code&gt; in our mutating handlers, we're pulling out the context added at this stage.&lt;/p&gt;

&lt;p&gt;There's also some logging added.  We trace the request's specifics and start a timer that reports how long the request took.  To see this logging in action, set the environment variable &lt;code&gt;RUST_LOG=info&lt;/code&gt; when executing the server process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Catching Panics
&lt;/h3&gt;

&lt;p&gt;The most exciting part (to me, at least) is the panic handler.  We always want our requests to succeed.  However, there are situations where we may encounter a &lt;code&gt;panic&lt;/code&gt;.  This will cause the entire Rust program to crash and print out a stack trace in normal usage.  However, this is a web service.  A panic situation in one request handling process shouldn't prevent other requests from executing.  We don't want the whole server to crash; we still want to handle these situations gracefully.  We can intercept the normal panic behavior and instead simply produce a different response containing the details.&lt;/p&gt;

&lt;p&gt;At the top, we create a task-local storage location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;task_local!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;PANIC_MESSAGE_AND_BACKTRACE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RefCell&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Backtrace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is local to just the currently executing Tokio task, not the whole program.  Then, we replace the default panic logic with our own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;hook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;take_hook&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set_hook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;panic_info&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;panic_info&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;Backtrace&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;PANIC_MESSAGE_AND_BACKTRACE&lt;/span&gt;&lt;span class="nf"&gt;.with&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="nf"&gt;.borrow_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set_hook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we grab the existing hook and store it to the &lt;code&gt;hook&lt;/code&gt; variable.  Then, we overwrite our own.  At the end of the function, we make sure to reset the global panic hook back to what it was.  If the task panics inside this function - for example, one of our &lt;code&gt;unwrap()&lt;/code&gt; statements encounter a non-success, we'll store the panic message and backtrace to this task-local location.  However, we will &lt;em&gt;not&lt;/em&gt; abort the process.&lt;/p&gt;

&lt;p&gt;Up above, in the &lt;code&gt;service&lt;/code&gt; location, we can catch this happening:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;AssertUnwindSafe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.catch_unwind&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We attempt to build the response, but this result will not be a success if anything happens.  If it was a success, great, we pass it back up.  However, if we find an error value here, we can dispatch different logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or_else&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PANIC_MESSAGE_AND_BACKTRACE&lt;/span&gt;&lt;span class="nf"&gt;.with&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="nf"&gt;.borrow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backtrace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;panic_message_and_backtrace&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;error!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;backtrace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;backtrace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"500"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backtrace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For most requests, that &lt;code&gt;result.unwrap()&lt;/code&gt; went fine, and we just stored our response to &lt;code&gt;Response&lt;/code&gt;.  However, if it was an error, we can read the result of the panic from this task-local area.  We emit an error trace on the server-side and then build a &lt;em&gt;new&lt;/em&gt; response with status code &lt;code&gt;INTERNAL_SERVER_EROR&lt;/code&gt;.  This response includes the full backtrace as the body.  This means our server can keep handling other requests without interruption, but the specific client that caused the panic gets a complete log of the problem, and our server has logged the backtrace as well.  We can diagnose the issue without losing uptime for any other client.&lt;/p&gt;

&lt;p&gt;Now, no matter what happened while processing the request, we've stored a valid &lt;code&gt;hyper::Response&lt;/code&gt; to this response value, and we can pass that back to the caller even if something catastrophic occurs.  We can safely use &lt;code&gt;Ok::&amp;lt;_, Infallible&amp;gt;&lt;/code&gt;, signifying that there is no possible way for control to fail to hit this point.  Our server will &lt;em&gt;always&lt;/em&gt; generate a response and continue, even if something terrible happens.  Good stuff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests
&lt;/h2&gt;

&lt;p&gt;Finally, we want to ensure we can automate tests. I'll just demonstrate a test of our 404 handler, which includes all the pieces needed to build a robust test suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;flate2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;write&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ZlibDecoder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pretty_assertions&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;assert_eq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;select&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;document&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nd"&gt;#[tokio::test]&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_four_oh_four&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/nonsense"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;RwLock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Todos&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
        &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="nf"&gt;.extensions_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NOT_FOUND&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;to_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.into_body&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;decoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ZlibDecoder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;decoder&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;uncompressed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;decoder&lt;/span&gt;&lt;span class="nf"&gt;.finish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uncompressed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="nf"&gt;.find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h1"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"NOT FOUND!"&lt;/span&gt;&lt;span class="nf"&gt;.to_owned&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tokio provides a &lt;code&gt;#[tokio::test]&lt;/code&gt; macro for building async tests.  We can use &lt;code&gt;hyper::Request&lt;/code&gt; to construct a request and build our context the same way we did in the server.  Because our handler is just a function from a &lt;code&gt;Request&lt;/code&gt; to a &lt;code&gt;Response&lt;/code&gt;, we can test it very simply: &lt;code&gt;let response = handle(request).await;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We first assert the status code matches what we expect, then we have to decode the body.  We use the &lt;code&gt;ZlibDecoder&lt;/code&gt; to read the response body and decompress it back to a string.&lt;/p&gt;

&lt;p&gt;Once we have our string response, we can use the &lt;a href="https://github.com/utkarshkukreti/select.rs"&gt;&lt;code&gt;select.rs&lt;/code&gt;&lt;/a&gt; library to ensure the structure matches our intent.  In this case, we are asserting we've received an &lt;code&gt;h1&lt;/code&gt; element with a text body matching the string &lt;code&gt;NOT FOUND!&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fin
&lt;/h2&gt;

&lt;p&gt;This implementation is an improvement over the previous in several fundamental ways.  The &lt;code&gt;async/.await&lt;/code&gt; syntax allows us to write code closely matching our intent without getting bogged down with &lt;code&gt;Box&lt;/code&gt;es and &lt;code&gt;Future&lt;/code&gt;s.  We avoid polluting the global scope and use the &lt;code&gt;Request&lt;/code&gt; itself to handle concurrent access to the app state and even catastrophic request handling errors gracefully without affecting other clients.  Our handler is straightforward to test.  This application provides a solid, performant base for building more complex applications and keeps the dependencies and therefore compile times and bundle sizes to a minimum.&lt;/p&gt;

&lt;p&gt;While there are many different frameworks for building web applications in Rust, it's worth asking yourself whether you actually need that level of abstraction.  For many web service needs, putting the building blocks together yourself isn't much more complicated, and you retain control over how you build your application.  If we want to deconstruct the request URI, we can do that already.  If we return JSON, we just need to create a struct that implements &lt;code&gt;serde::Serialize&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The conclusion here is the same as before: when the end goal is simple enough, why not use simple tools?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@dannyhowe?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Danny Howe&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/festival?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Prepare your Rust API docs for Github Pages</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Tue, 09 Nov 2021 01:30:45 +0000</pubDate>
      <link>https://forem.com/deciduously/prepare-your-rust-api-docs-for-github-pages-2n5i</link>
      <guid>https://forem.com/deciduously/prepare-your-rust-api-docs-for-github-pages-2n5i</guid>
      <description>&lt;p&gt;Rust comes with a built-in documentation system, &lt;a href="https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html" rel="noopener noreferrer"&gt;&lt;code&gt;rustdoc&lt;/code&gt;&lt;/a&gt;.  It's great, use it.&lt;/p&gt;

&lt;p&gt;Github comes with a built-in web hosting service, &lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;Github Pages&lt;/a&gt;.  It's great, use it.&lt;/p&gt;

&lt;p&gt;To use Github Pages, you can either create a directory in your repository to host your deployed web content or a separate branch and then activate the feature in the "Pages" section of your repository settings:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8lir12pnvm9v9v9q1go.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8lir12pnvm9v9v9q1go.png" alt="settings screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great!&lt;/p&gt;

&lt;p&gt;You get a directory located at &lt;code&gt;&amp;lt;project&amp;gt;/target/doc&lt;/code&gt; when you run &lt;code&gt;cargo doc&lt;/code&gt; to generate your Rust documentation.  It contains the complete web content ready to publish.  If you execute &lt;code&gt;cargo doc --open&lt;/code&gt;, your default browser will open up and show you what it generated.&lt;/p&gt;

&lt;p&gt;Unfortunately, this folder can't be copied strictly as-is.  If you try, you'll get a 404.  This is because Github Pages is looking for an &lt;code&gt;index.html&lt;/code&gt; file in the root directory of wherever it's pointed.  However, &lt;code&gt;cargo doc&lt;/code&gt; created a &lt;em&gt;subdirectory&lt;/em&gt; for your crate specifically, where &lt;code&gt;index.html&lt;/code&gt; lives.  Here's my example for a Rust package called &lt;code&gt;build_wheel&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ tree target/doc/
target/doc
├── ayu.css
├── brush.svg
├── build_wheel
│  ├── all.html
│  ├── fn.build_wheel.html
│  ├── index.html          &amp;lt;-- RIGHT HERE
│  ├── sidebar-items.js
│  ├── struct.Config.html
│  └── struct.Tag.html
├── clipboard.svg
/* ... etc, etc... */


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Uh-oh, it's nested.  Github can't find it.  You can't just make a symbolic link to an &lt;code&gt;index.html&lt;/code&gt; in the root directory because all the relative links inside will break.&lt;/p&gt;

&lt;p&gt;Luckily, the fix is easy.  You simply need to create an &lt;code&gt;index.html&lt;/code&gt; that reroutes where you want.  This file only consists of one line:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"refresh"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"0; url=build_wheel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This file uses the &lt;a href="https://www.w3schools.com/tags/att_meta_http_equiv.asp" rel="noopener noreferrer"&gt;&lt;code&gt;http-equiv&lt;/code&gt;&lt;/a&gt; meta attribute to point immediately to the &lt;code&gt;build_wheel&lt;/code&gt; subdirectory and load the &lt;code&gt;index.html&lt;/code&gt; file found there.  Just replace the directory name with the name of your package.&lt;/p&gt;

&lt;p&gt;You can easily automate this in a simple script:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

cargo doc &lt;span class="nt"&gt;--no-deps&lt;/span&gt;
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ./docs
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;meta http-equiv=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;refresh&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; content=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;0; url=build_wheel&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; target/doc/index.html
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; target/doc ./docs


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Feel free to get as fancy as you want for pulling the actual name. I've just hardcoded it ¯\&lt;em&gt;(ツ)&lt;/em&gt;/¯.&lt;/p&gt;

&lt;p&gt;When Github Pages tries to build your content, now it will find this root index page.  Users will load this page and immediately refresh the page you intended to display, and all the internal links generated by &lt;code&gt;rustdoc&lt;/code&gt; will work as expected.&lt;/p&gt;

&lt;p&gt;Neat.&lt;/p&gt;

&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@kellysikkema?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Kelly Sikkema&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/instructions?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>rust</category>
      <category>github</category>
    </item>
    <item>
      <title>Workstation Management With Nix Flakes: Build a Cmake C++ Package</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Sun, 31 Oct 2021 15:42:35 +0000</pubDate>
      <link>https://forem.com/deciduously/workstation-management-with-nix-flakes-build-a-cmake-c-package-21lp</link>
      <guid>https://forem.com/deciduously/workstation-management-with-nix-flakes-build-a-cmake-c-package-21lp</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/deciduously/workspace-management-with-nix-flakes-jupyter-notebook-example-2kke"&gt;Last time&lt;/a&gt;, we looked at how to produce a development shell using Nix Flakes that contained the Python interpreter alongside a few dependencies the project required. In this post, we'll create a compiled binary, using source code hosted on GitHub, for other people to include in their environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Target
&lt;/h2&gt;

&lt;p&gt;For this demonstration, I'll be packaging the &lt;a href="https://github.com/microsoft/LightGBM"&gt;LightGBM&lt;/a&gt; CLI tool. Nixpkgs already provides derivations for the native libraries for Python and R, which will suffice for most users, but I didn't see one to build the CLI tool directly (and, of course, will submit mine upstream as well).&lt;/p&gt;

&lt;p&gt;Per &lt;a href="https://lightgbm.readthedocs.io/en/latest/Installation-Guide.html#linux"&gt;the documentation&lt;/a&gt;, building this application from source is relatively straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone --recursive https://github.com/microsoft/LightGBM
cd LightGBM
mkdir build
cd build
cmake ..
make -j4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can learn a few things: this git repository has submodules, meaning we need to use &lt;code&gt;--recursive&lt;/code&gt;, and the build can be parallelized. These instructions also have you create a build directory, but with Nix, we can skip that. The whole build will take place in a purpose-made build directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Flake
&lt;/h2&gt;

&lt;p&gt;As before, I'll show the complete flake first. We'll walk through it in pieces below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:nixos/nixpkgs/nixos-unstable"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nv"&gt;flake-utils&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:numtide/flake-utils"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nv"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;flake-utils&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nv"&gt;flake-utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;eachDefaultSystem&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt;
      &lt;span class="nv"&gt;pkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;inherit&lt;/span&gt; &lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="nv"&gt;lightgbm-cli&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;stdenv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkDerivation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;pname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lightgbm-cli"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nv"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3.3.1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nv"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;fetchgit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/microsoft/LightGBM"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;rev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"v3.3.1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;sha256&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pBrsey0RpxxvlwSKrOJEBQp7Hd9Yzr5w5OdUuyFpgF8="&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;fetchSubmodules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;};&lt;/span&gt;
          &lt;span class="nv"&gt;nativeBuildInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="nv"&gt;clang&lt;/span&gt;
            &lt;span class="nv"&gt;cmake&lt;/span&gt;
          &lt;span class="p"&gt;];&lt;/span&gt;
          &lt;span class="nv"&gt;buildPhase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"make -j $NIX_BUILD_CORES"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nv"&gt;installPhase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;            mkdir -p $out/bin&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;            mv $TMP/LightGBM/lightgbm $out/bin&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;          ''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;rec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;defaultApp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;flake-utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkApp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;drv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;defaultPackage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="nv"&gt;defaultPackage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lightgbm-cli&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;devShell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkShell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;buildInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="nv"&gt;lightgbm-cli&lt;/span&gt;
        &lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you read the last post, much of this looks the same. We have &lt;code&gt;inputs&lt;/code&gt; and &lt;code&gt;outputs&lt;/code&gt;, a &lt;code&gt;let...in&lt;/code&gt; section defining variables, and a &lt;code&gt;devShell&lt;/code&gt; in the output.&lt;/p&gt;

&lt;p&gt;The new bits are the &lt;code&gt;lightgbm-cli&lt;/code&gt; variable, defined using &lt;code&gt;stdenv.mkDerivation&lt;/code&gt;, and the &lt;code&gt;defaultApp&lt;/code&gt; and &lt;code&gt;defaultPackage&lt;/code&gt; keys in the &lt;code&gt;outputs&lt;/code&gt; section.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Walkthrough
&lt;/h2&gt;

&lt;p&gt;I won't repeat the explanations of the shared elements. Take a look at the &lt;a href="https://dev.to/deciduously/workspace-management-with-nix-flakes-jupyter-notebook-example-2kke"&gt;previous post&lt;/a&gt; for the full descriptions. This post will focus on the &lt;code&gt;mkDerivation&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;pkgs.stdenv.mkDerivation&lt;/code&gt; function is a wrapper around the low-level Nix concept of a &lt;code&gt;derivation&lt;/code&gt;. See the &lt;a href="https://nixos.org/guides/nix-pills/our-first-derivation.html"&gt;Nix Pills&lt;/a&gt; for a thorough walkthrough of how to work with them. Using &lt;code&gt;mkDerivation&lt;/code&gt; sets some sensible defaults. It provides more tools on top of this base to greatly streamline the process, but it's important to know that this &lt;code&gt;derivation&lt;/code&gt; concept is what ultimately gets evaluated under the hood.&lt;/p&gt;

&lt;p&gt;We want to refer to this derivation in multiple places, so it gets a specific name assigned in the &lt;code&gt;let...in&lt;/code&gt; block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;lightgbm-cli&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;stdenv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkDerivation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By prefixing the function using &lt;code&gt;with pkgs;&lt;/code&gt; we can avoid explicitly referring to &lt;code&gt;pkgs&lt;/code&gt; every time we use something from this set. The first example is right here. the &lt;code&gt;stdenv&lt;/code&gt; object lives in &lt;code&gt;pkgs&lt;/code&gt;, so fully qualified, this opener would be &lt;code&gt;pkgs.stdenv.mkDerivation&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Name
&lt;/h3&gt;

&lt;p&gt;Inside, we first set the package name. You can directly set a &lt;code&gt;name&lt;/code&gt;, but the preferred way to handle this is to set the package name using &lt;code&gt;pname&lt;/code&gt;, and the version separately. Nix will then combine them into a whole &lt;code&gt;name&lt;/code&gt; key for you with the format &lt;code&gt;${pname}-${version}&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;pname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lightgbm-cli"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3.3.1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Source
&lt;/h3&gt;

&lt;p&gt;Then, we need to point Nix at our source code. If you were packaging a source that you were building yourself, and this flake lived in the project directory, you could point at the current folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;./.&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, we're just creating a derivation for an existing codebase hosted online in a Git repository. We can use the &lt;code&gt;pkgs.fetchgit&lt;/code&gt; function to direct Nix to download the source directly before building:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;fetchgit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/microsoft/LightGBM"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;rev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"v3.3.1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;sha256&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pBrsey0RpxxvlwSKrOJEBQp7Hd9Yzr5w5OdUuyFpgF8="&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;fetchSubmodules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We provide the URL and the specific tag, so we're not just pointing right at the main branch. You can also set a particular commit, tagged or not, by giving the complete git commit hash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;rev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"d4851c3381495d9a065d49e848fbf291a408477d"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we didn't need to fetch any submodules, and the repo was on GitHub specifically, there's an even better function to use called &lt;code&gt;pkgs.fetchFromGithub&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;fetchFromGitHub&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"microsoft"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"LightGBM"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;rev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"v3.3.1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sha256-pBrsey0RpxxvlwSKrOJEBQp7Hd9Yzr5w5OdUuyFpgF8="&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't need to provide a full URL, Nix needs the owner and repo name, and you can use the more generic &lt;code&gt;hash&lt;/code&gt; key, prefixing the actual hash so that Nix knows how to resolve it. However, I was unable to get this working with submodules, and this wouldn't work for code hosted elsewhere, like &lt;a href="https://about.gitlab.com/"&gt;GitLab&lt;/a&gt; or &lt;a href="https://sr.ht/"&gt;sourcehut&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before you run your derivation the first time, you probably won't know the sha256 hash of the source repository. While you could download it separately and use the &lt;code&gt;nix hash-path path/to/clone&lt;/code&gt; command, I find it more convenient to provide a bad hash first and let Nix tell you what it should be. There's even a built-in feature for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;sha256&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;fakeSha256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the first run, you'll get an error like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nix build
error: hash mismatch in fixed-output derivation '/nix/store/5ysvmxay83fnc14w5r2s450i39byd4ks-source.drv':
         specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
            got:    sha256-pBrsey0RpxxvlwSKrOJEBQp7Hd9Yzr5w5OdUuyFpgF8=
error: 1 dependencies of derivation '/nix/store/jaip55q9ix8hq4l7srd9kigxlq7nimyr-lightgbm-cli-3.3.1.drv' failed to build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It downloaded the repository, checked the hash, and (thankfully) noticed it's not the same as the &lt;code&gt;fakeSha256&lt;/code&gt; hash you provided. Conveniently, it tells us what the hash &lt;em&gt;should&lt;/em&gt; be so that you can change your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- sha256 = lib.fakeSha256;
&lt;/span&gt;&lt;span class="gi"&gt;+ sha256 = "pBrsey0RpxxvlwSKrOJEBQp7Hd9Yzr5w5OdUuyFpgF8=";
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you rerun it, the hashes will match, and Nix will continue to the next phase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inputs
&lt;/h3&gt;

&lt;p&gt;Now that we have the source, we need to tell Nix what tools are necessary to build the software. We can use the &lt;code&gt;nativeBuildInputs&lt;/code&gt; key for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;nativeBuildInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nv"&gt;clang&lt;/span&gt;
  &lt;span class="nv"&gt;cmake&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configuration is handled via &lt;code&gt;cmake&lt;/code&gt;, and we'll have &lt;code&gt;clang&lt;/code&gt; be our C++ compiler.&lt;/p&gt;

&lt;h3&gt;
  
  
  Package
&lt;/h3&gt;

&lt;p&gt;To control the build, you can use the phases provided by &lt;code&gt;mkDerviation&lt;/code&gt;: &lt;code&gt;unpack&lt;/code&gt;, &lt;code&gt;patch&lt;/code&gt;, &lt;code&gt;configure&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;, &lt;code&gt;check&lt;/code&gt;, and &lt;code&gt;install&lt;/code&gt;. However, if you need default behavior for any of these, you can omit them. You only need to define logic when it differs from the defaults. To learn more about these phases, see &lt;a href="https://github.com/samdroid-apps/nix-articles/blob/master/04-proper-mkderivation.md"&gt;this article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Setting &lt;code&gt;cmake&lt;/code&gt; in our &lt;code&gt;nativeBuildInputs&lt;/code&gt; means that Nix already configures this project by default. We don't have any unique unpacking to do or any patches to apply, and we're not going to check the compiled output. These defaults mean we only need to define a &lt;code&gt;buildPhase&lt;/code&gt; and an &lt;code&gt;installPhase&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;build&lt;/code&gt; part is easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;buildPhase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"make -j $NIX_BUILD_CORES"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By this point, Nix has already implicitly run &lt;code&gt;cmake .&lt;/code&gt;, so our Makefiles are in place and ready to go. We could omit this phase and have Nix execute &lt;code&gt;make&lt;/code&gt;, but we want to use as many cores as possible to speed up the build. Nix provides a special environment variable &lt;code&gt;$NIX_BUILD_CORES&lt;/code&gt; that we can pass to &lt;code&gt;make&lt;/code&gt;'s job flag to be sure this build runs as efficiently as it can.&lt;/p&gt;

&lt;p&gt;Then, we need to copy the resulting binary to the output of the flake:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;installPhase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;  mkdir -p $out/bin&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;  mv $TMP/LightGBM/lightgbm $out/bin&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result of your derivation gets assigned a special &lt;code&gt;$out&lt;/code&gt; variable. If your derivation ultimately produces one or more binaries, you can create a &lt;code&gt;$out/bin&lt;/code&gt; directory to hold these. Any Nix expression that depends on your derivation will automatically add the contents of this directory to your &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this case, we need the &lt;code&gt;lightgbm&lt;/code&gt; executable file produced in the &lt;code&gt;build&lt;/code&gt; phase. When we downloaded the GitHub source, Nix placed it in the &lt;code&gt;LightGBM&lt;/code&gt; directory within the special &lt;code&gt;$TMP&lt;/code&gt; build directory for the derivation. &lt;code&gt;$TMP&lt;/code&gt; is an alias for &lt;code&gt;$NIX_BUILD_TOP&lt;/code&gt;. You can also use &lt;code&gt;$TMPDIR&lt;/code&gt;, &lt;code&gt;$TEMPDIR&lt;/code&gt;, or &lt;code&gt;TEMP&lt;/code&gt;. Nix creates all these while running your derivation to prevent processes from using &lt;code&gt;/tmp&lt;/code&gt; outside this special Nix-y place.&lt;/p&gt;

&lt;p&gt;If you had opted to pin to a specific commit instead of a tag, this folder would be called, e.g. &lt;code&gt;$TMP/LightGBM-d4581c3&lt;/code&gt;, including the beginning of the complete commit hash.&lt;/p&gt;

&lt;p&gt;If you get confused about the directory structure, I find the easiest trick is to dump the whole thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;installPhase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;  mkdir $out&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;  cp -r $TMP $out&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run &lt;code&gt;nix build&lt;/code&gt;, you'll see the entire contents of the build directory in the &lt;code&gt;result&lt;/code&gt; symlink, which you can explore to understand where everything ended up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fixed-Output Derivations
&lt;/h3&gt;

&lt;p&gt;I don't use this feature directly in this example, but it's worth mentioning that you don't have access to the internet in your phase descriptions. This restriction is to keep Nix derivations pure. However, what if you wanted to? You might need to &lt;code&gt;curl&lt;/code&gt; something or use &lt;code&gt;maven&lt;/code&gt; to download dependencies before building. There are myriad reasons you may wish to access the internet beyond simply grabbing the source code to build a given project.&lt;/p&gt;

&lt;p&gt;To allow this to happen, you can provide an output hash of the result so that Nix can prove to itself that your derivation is reproducible. Like before, you won't know this result ahead of time, so you'll need to watch it fail once and tell you the intended result, but once you add that to your flake, Nix will happily grab these remote files and include them in your derivation result.&lt;/p&gt;

&lt;p&gt;First, you need to add &lt;code&gt;cacert&lt;/code&gt; to your derivation and set the &lt;code&gt;SSL_CERT_FILE&lt;/code&gt; variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;buildInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;cacert&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nv"&gt;SSL_CERT_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;cacert&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/etc/ssl/certs/ca-bundle.crt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, Nix will pull the required SSL certificates into the build sandbox so that tools like &lt;code&gt;curl&lt;/code&gt; can access them to make network requests.&lt;/p&gt;

&lt;p&gt;Then, you add the hash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;outputHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sha256-I4UGDcrtmX/1TAQz89peXsqoetZmCM+1b3XYqexv/VA="&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This config should be sufficient if your derivation result is a file. However, if you're producing a folder structure, you'll also need to add this key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;outputHashMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"recursive"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, &lt;code&gt;outputHashMode&lt;/code&gt; is set to &lt;code&gt;"flat"&lt;/code&gt;, so it will fail to hash a recursive directory tree properly. Luckily it's easy enough to toggle. Your derivation is still totally reproducible and safe to use in a pure evaluation environment, even if it requires downloading additional files from the internet.&lt;/p&gt;

&lt;p&gt;In fact, this is what the &lt;code&gt;pkgs.fetchgit&lt;/code&gt; convenience helper is doing under the hood.  &lt;em&gt;Everything&lt;/em&gt; in Nix is a derivation, and the hash you provide to this function gets used to satisfy this exact requirement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Outputs
&lt;/h3&gt;

&lt;p&gt;Now, the &lt;code&gt;lightgbm-cli&lt;/code&gt; variable points to the complete derivation. For usage, we want this flake to be usable via &lt;code&gt;nix build&lt;/code&gt; using &lt;code&gt;defaultPackage&lt;/code&gt;, &lt;code&gt;nix develop&lt;/code&gt; using &lt;code&gt;devShell&lt;/code&gt;, or &lt;code&gt;nix run&lt;/code&gt; using &lt;code&gt;defaultApp&lt;/code&gt;. All of these are easy to do now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;defaultApp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;flake-utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkApp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;drv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;defaultPackage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nv"&gt;defaultPackage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lightgbm-cli&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;devShell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkShell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;buildInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nv"&gt;lightgbm-cli&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, users can access a ready-made &lt;code&gt;lightgbm&lt;/code&gt; executable no matter how they intend to interact with this flake or integrate it into their environments. We lean on the &lt;code&gt;mkApp&lt;/code&gt; feature provided by &lt;code&gt;flake-utils&lt;/code&gt; to produce the particular structure required by &lt;code&gt;defaultApp&lt;/code&gt;/&lt;code&gt;nix run&lt;/code&gt; and pass it the &lt;code&gt;defaultPackage&lt;/code&gt; key. Because this whole block was marked &lt;code&gt;rec&lt;/code&gt;, it doesn't matter what order we define them. Nix will recursively evaluate this block until everything is thoroughly defined.&lt;/p&gt;

&lt;p&gt;If you have Nix installed, you should be able to create a new folder, paste the contents above into &lt;code&gt;flake.nix&lt;/code&gt;, and use these commands to grab, compile, and use &lt;code&gt;lightgbm&lt;/code&gt; yourself no matter what platform you're using.&lt;/p&gt;

&lt;p&gt;Neat!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@hngstrm?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Henry &amp;amp; Co.&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/builder?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>cpp</category>
      <category>beginners</category>
      <category>nix</category>
    </item>
    <item>
      <title>Workstation Management With Nix Flakes: Jupyter Notebook Example</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Sat, 30 Oct 2021 13:58:52 +0000</pubDate>
      <link>https://forem.com/deciduously/workspace-management-with-nix-flakes-jupyter-notebook-example-2kke</link>
      <guid>https://forem.com/deciduously/workspace-management-with-nix-flakes-jupyter-notebook-example-2kke</guid>
      <description>&lt;h2&gt;
  
  
  What?
&lt;/h2&gt;

&lt;p&gt;If you're reading DEV, your computer is probably your primary productivity tool.  Whether it's a job, a hobby, or just a point of interest, your ability to install and use different types of software with ease is integral to your ability to keep learning and working.&lt;/p&gt;

&lt;p&gt;This means that many of us end up with &lt;em&gt;complicated&lt;/em&gt; workstation needs, with an interconnected web of dependency interactions.  If you need to wipe your hard drive and start over, it would likely take a non-trivial amount of work to set everything back up &lt;em&gt;exactly&lt;/em&gt; the same way, and each piece needs to be managed separately.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nixos.org/"&gt;Nix&lt;/a&gt; is a tool designed to take the pain out of workspace management.  Nix is &lt;a href="https://en.wikipedia.org/wiki/Declarative_programming"&gt;declarative&lt;/a&gt;.  You're not telling the computer how to build your environment step-by-step; you're simply describing the end state you need.  Nix learns how to make it and then stores everything you need in a reproducible way so that subsequent invocations are near-instant.  It is also unified.  Every tool you use can be managed this way, with lots of built-in functionality for quickly setting up complex environments with minimal effort on your part.&lt;/p&gt;

&lt;p&gt;This post will show you how I'm using Nix to manage my &lt;a href="https://www.python.org/"&gt;Python&lt;/a&gt; environment and dependencies for using &lt;a href="https://jupyter.org/"&gt;Jupyter Notebooks&lt;/a&gt; for school assignments.  However, this same strategy can be used to build environments for whatever tool you need.&lt;/p&gt;

&lt;p&gt;If you just want to see the config file, jump down to The Flake.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who?
&lt;/h2&gt;

&lt;p&gt;While Nix can control your entire operating system, you don't need to go all-in to reap the benefits.  You can install the Nix package manager on Linux (i686, x86_64, or aarch64) or macOS (currently just x86_64, but ARM support will show up eventually).  See the &lt;a href="https://nixos.org/manual/nix/stable/#chap-quick-start"&gt;Quick Start&lt;/a&gt; guide to get up and running.&lt;/p&gt;

&lt;p&gt;This post uses a new feature of Nix called Nix Flakes, which you need to enable after you install.  See the &lt;a href="https://nixos.wiki/wiki/Flakes"&gt;Flakes wiki page&lt;/a&gt; and look for the "Non-NixOS" section.  I promise it's not too hard.&lt;/p&gt;

&lt;p&gt;However, if you end up liking what you see, I think NixOS is the best way to use Nix.  Just recently, I ended up wiping my hard drive.  I re-partitioned and then ran &lt;em&gt;one single command&lt;/em&gt;.  After letting it build, I could boot into an operating system identical to how I had left it, with all my tools installed and configuration settings set.  That's pretty hard to beat.  You can see &lt;a href="https://github.com/deciduously/nixos-config"&gt;my personal config on Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Python is a great programming language.  It has both a low barrier of entry for people learning the craft and a bustling ecosystem for scientific/numerical computing and web development (and much, much more).&lt;/p&gt;

&lt;p&gt;However, one sticking point for me has always been dependency management.  For most Python uses, you will need to install some packages, and keeping this organized is not always straightforward.&lt;/p&gt;

&lt;p&gt;I'm using this example specifically because I recently started taking a class that uses Jupyter Notebooks for assignments and labs.  I love Jupyter. It's an excellent tool for this sort of thing and is pretty widely used.  However, when I opened up my first assignment, the first interactive cell contained these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this is super standard and to be expected, I still felt myself thinking, "Oh boy, here we go again."&lt;/p&gt;

&lt;p&gt;There is a tool for installing dependencies. It's not like you're just manually downloading Python files, putting them in a sensible place yourself, and somehow telling your Python interpreter where to find them (looking at you, C and C++).  We have &lt;code&gt;pip&lt;/code&gt;!  With a properly configured Python installation, you can just type &lt;code&gt;pip install numpy&lt;/code&gt;, and the tool will automatically take care of the details.&lt;/p&gt;

&lt;p&gt;However, this installs to a &lt;em&gt;global&lt;/em&gt; location.  Every Python program in any project on your computer will refer to the same place.  No good - what if you want to run some code that depends on a different version of some package?&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;numpy&lt;/code&gt; dependency isn't a global dependency of your python installation. The need is local to whatever you're currently doing.  There's an answer for that as well, of course.  It involves, well, a &lt;code&gt;virtualenv&lt;/code&gt;, a requirements file, and a substantial local folder with a full copy of your environment.  This environment is pretty specific to exactly how it was installed too.  If anything happens to it, or you change computers, you have to start over.&lt;/p&gt;

&lt;p&gt;It, you know, works, but it doesn't exactly "spark joy" for me.  With each new Python project, the tangled mess that comprises "my workstation" grows, and I don't need that kind of background anxiety in my life.&lt;/p&gt;

&lt;h2&gt;
  
  
  How?
&lt;/h2&gt;

&lt;p&gt;With Nix, we have a &lt;em&gt;declarative&lt;/em&gt; solution.  We can create one text file and describe what we need, and Nix will get it done.  This file will work the same way anywhere we want to use it and doesn't leave brittle artifacts littered in our project codebase.  As long as this single text file is present in your project, you can produce the environment you need the same exact way every time and pretty much just forget about the whole thing.  It will even work if we drop it into a different computer running on a different platform and OS, as long as it's supported by Nix.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Flake
&lt;/h3&gt;

&lt;p&gt;I'll start by showing you the whole file, and we'll dig through it in pieces below.  This gets saved as &lt;code&gt;flake.nix&lt;/code&gt; in the top level of your project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:nixos/nixpkgs/nixos-unstable"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nv"&gt;flake-utils&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:numtide/flake-utils"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nv"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;flake-utils&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nv"&gt;flake-utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;eachDefaultSystem&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt;
      &lt;span class="nv"&gt;pkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;inherit&lt;/span&gt; &lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;rec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;devShell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkShell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;buildInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;python3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;withPackages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;ps&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="nv"&gt;ipython&lt;/span&gt;
            &lt;span class="nv"&gt;jupyter&lt;/span&gt;
            &lt;span class="nv"&gt;numpy&lt;/span&gt;
            &lt;span class="nv"&gt;pandas&lt;/span&gt;
          &lt;span class="p"&gt;]))&lt;/span&gt;
        &lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;shellHook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"jupyter notebook"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not so bad, right?  Let's take a closer look from the outside in.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Walkthrough
&lt;/h3&gt;

&lt;p&gt;A Nix Flake is just an object - check out those surrounding curly braces.  This object has two keys, &lt;code&gt;inputs&lt;/code&gt; and &lt;code&gt;outputs&lt;/code&gt;.  The inputs are where we define the flake's dependencies and where to find all the tools we use.  This one has two, &lt;a href="https://github.com/NixOS/nixpkgs"&gt;&lt;code&gt;nixpkgs&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/numtide/flake-utils"&gt;&lt;code&gt;flake-utils&lt;/code&gt;&lt;/a&gt;.  Each of these just points to a GitHub URL, and if you follow those links, you'll see each repo provides its own &lt;code&gt;flake.nix&lt;/code&gt;.  The &lt;code&gt;outputs&lt;/code&gt; of each remote flake get piped into the &lt;code&gt;inputs&lt;/code&gt; of my flake, so we can use what they provide.&lt;/p&gt;

&lt;p&gt;Next, we define our own output object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;flake-utils&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nv"&gt;flake-utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;eachDefaultSystem&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c"&gt;# ...&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We specifically bring each name we need from the inputs with &lt;code&gt;{{ nixpkgs, flake-utils, ... }}&lt;/code&gt; so we can refer to them inside, then use a tool from &lt;code&gt;flakeUtils&lt;/code&gt; called &lt;code&gt;eachDefaultSystem&lt;/code&gt;.  This is a convenience helper.  It provides a special variable called &lt;code&gt;system&lt;/code&gt; (see, right at the end: &lt;code&gt;(system:&lt;/code&gt;) which refers to the specific platform you're on.  On my computer, this resolves to &lt;code&gt;x86_64-linux&lt;/code&gt;.  This means we can use the exact same flake on any supported system, and Nix will know how to find the correct versions of anything inside.&lt;/p&gt;

&lt;p&gt;First, we create a special &lt;code&gt;pkgs&lt;/code&gt; variable to refer to the Nix package repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt;
  &lt;span class="nv"&gt;pkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;inherit&lt;/span&gt; &lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;rec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;#...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're a functional programmer, you might recognize the &lt;code&gt;let...in&lt;/code&gt; pattern.  We're just defining variables to be used below.  This flake just needs the one, and using &lt;code&gt;inherit system&lt;/code&gt; - the &lt;code&gt;system&lt;/code&gt; from just above - we can expressly point to the subset of &lt;code&gt;nixpkgs&lt;/code&gt; that applies to our platform.  We add &lt;code&gt;rec&lt;/code&gt; to allow Nix to fully resolve any Nix variables in the following object recursively until thoroughly evaluated.&lt;/p&gt;

&lt;p&gt;To discover what's available, you can use the &lt;a href="https://search.nixos.org/packages"&gt;NixOS Search&lt;/a&gt; page - yes, this applies to Nix users on other operating systems as well.&lt;/p&gt;

&lt;p&gt;Finally, we're ready to tell Nix what we need.  This flake doesn't build a package; it just defines a development shell.  We can activate it by using the command &lt;code&gt;nix develop&lt;/code&gt; from anywhere in this folder.  This is called a &lt;code&gt;devShell&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;devShell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkShell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;#...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To build it, we can use the built-in &lt;a href="https://nixos.wiki/wiki/Development_environment_with_nix-shell"&gt;&lt;code&gt;mkShell&lt;/code&gt;&lt;/a&gt; feature.  This is contained in &lt;code&gt;pkgs&lt;/code&gt;, which we've already appropriately configured above.&lt;/p&gt;

&lt;p&gt;We want this shell to have stuff available for use, using the &lt;code&gt;buildInputs&lt;/code&gt; key of &lt;code&gt;mkShell&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;buildInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;python3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;withPackages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;ps&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="nv"&gt;ipython&lt;/span&gt;
            &lt;span class="nv"&gt;jupyter&lt;/span&gt;
            &lt;span class="nv"&gt;numpy&lt;/span&gt;
            &lt;span class="nv"&gt;pandas&lt;/span&gt;
          &lt;span class="p"&gt;]))&lt;/span&gt;
        &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use &lt;code&gt;with pkgs;&lt;/code&gt; first, so that we don't have to fully qualify &lt;code&gt;pkgs.python3&lt;/code&gt; for each package inside, but that's what we mean for each item in this array.&lt;/p&gt;

&lt;p&gt;This array only contains one input, &lt;code&gt;python3&lt;/code&gt;.  However, we don't want just a plain Python environment. We know some packages we'll need access to already.  This is the part that replaces the &lt;code&gt;virtualenv&lt;/code&gt; setup entirely.  We can use the &lt;code&gt;withPackages&lt;/code&gt; option to define the list: this environment will grab &lt;code&gt;ipython&lt;/code&gt;, &lt;code&gt;jupyter&lt;/code&gt;, &lt;code&gt;numpy&lt;/code&gt;, and &lt;code&gt;pandas&lt;/code&gt; for us.  This will install Jupyter for us and the packages used inside, so the import statements from above will just work without any further action on your part.  If you need a new package at any point, you can just add it to this list and re-run &lt;code&gt;nix develop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Additionally, you can pin to a minor version of Python by simply replacing &lt;code&gt;python3&lt;/code&gt; in the snippet with, for example, &lt;code&gt;python39&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, to make this as easy as possible to use for this purpose, we can have it immediately launch Jupyter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;shellHook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"jupyter notebook"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can run any arbitrary code here. This will execute immediately once the environment is ready.  You can use multiple lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;shellHook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;  mkdir cool_dir&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;  echo "cool file contents" &amp;gt; cool_dir/cool_file.txt&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;  jupyter notebook&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't go anywhere without my &lt;code&gt;cool_file.txt&lt;/code&gt;, and Nix definitely can deliver.&lt;/p&gt;

&lt;p&gt;With my particular &lt;code&gt;shellHook&lt;/code&gt; in place, running &lt;code&gt;nix develop&lt;/code&gt; in this folder will automatically launch the Jupyter server and open the landing page in my browser.  I just store all my &lt;code&gt;.ipynb&lt;/code&gt; files in the same directory, and they're all ready to use.  I am &lt;em&gt;thrilled&lt;/em&gt; that I could use Nix to escape all the Python package management problems I've experienced in the past with under 30 lines of config.  This solution is portable, reproducible, and once you understand the building blocks, easy to use and adapt.&lt;/p&gt;

&lt;p&gt;The first time you run &lt;code&gt;nix develop&lt;/code&gt; will be the slowest because Nix needs to download everything from scratch.  However, once it's in your nix store, subsequent runs will be rapid.  If nothing has changed, it will be instant, and if you tweak something, it will only recalculate the difference.&lt;/p&gt;

&lt;p&gt;The inputs are hashed, so you always use the same revision upstream.  You can run &lt;code&gt;nix flake update&lt;/code&gt; to grab updated hashes if you want to pull in new changes.  This will update the &lt;code&gt;flake.lock&lt;/code&gt; file that Nix creates and manages.&lt;/p&gt;

&lt;p&gt;Your Nix store will grow over time because it will keep fully specified and hashed versions of whatever you use.  To clean up unneeded files, you can periodically run &lt;code&gt;nix-collect-garbage&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Okay, And?
&lt;/h2&gt;

&lt;p&gt;This example is just a taste.  You can use Nix to completely manage your entire workstation from the ground up, as well as declaratively package any type of application you would like to distribute to others.&lt;/p&gt;

&lt;p&gt;In future posts, we'll look at how to package your code for others to use, how to use Nix Flakes to define your entire operating system, and take a deeper look at what Nix is doing under the hood to turn these files into development environments.&lt;/p&gt;

&lt;p&gt;Nix is a vast topic, but it can significantly streamline how you manage your computer and the tools you need every day.  If there's something specific you'd like to see in this series, please let me know!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@chuttersnap?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;CHUTTERSNAP&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/boxes?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>jupyter</category>
      <category>beginners</category>
      <category>nix</category>
    </item>
    <item>
      <title>Pretend You're Using A Different Linux Distribution With One Docker Command</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Mon, 25 Oct 2021 19:14:29 +0000</pubDate>
      <link>https://forem.com/deciduously/pretend-youre-using-a-different-linux-distribution-with-one-docker-command-45k1</link>
      <guid>https://forem.com/deciduously/pretend-youre-using-a-different-linux-distribution-with-one-docker-command-45k1</guid>
      <description>&lt;h2&gt;
  
  
  The Why
&lt;/h2&gt;

&lt;p&gt;Lots of developers use Linux, but "Linux" is a vast category.  There are a lot of similarities, but a lot of differences, too.  &lt;a href="https://ubuntu.com/"&gt;Ubuntu&lt;/a&gt; and &lt;a href="https://getfedora.org/"&gt;Fedora&lt;/a&gt; look and feel pretty similar until you try to install a package - whoops, &lt;code&gt;apt&lt;/code&gt; is a little different than &lt;code&gt;dnf&lt;/code&gt;. Specific system settings may be stored in different places, and particular commands may be included by default in one but not the other.  Then there's even more niche stuff like &lt;a href="https://archlinux.org/"&gt;Arch&lt;/a&gt;, which you install piece by piece from a very minimal package set, or &lt;a href="https://www.gentoo.org/"&gt;Gentoo&lt;/a&gt;, which is similar to Arch with the additional caveat that the user compiles all the software locally for their specific hardware.  Users of these distros may end up with pretty different-looking operating systems that all fall under the broad Linux umbrella.&lt;/p&gt;

&lt;p&gt;All of the above adhere to a structure called the &lt;a href="https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard"&gt;Filesystem Hierarchy Standard&lt;/a&gt;, FHS for short.  This specifies the standard top-level hierarchy common to these different flavors, like &lt;code&gt;/etc&lt;/code&gt; for configuration, &lt;code&gt;/boot&lt;/code&gt; for bootloader files, &lt;code&gt;/proc&lt;/code&gt; for process management, and &lt;code&gt;/home&lt;/code&gt; for user-specific home directories.  See the Wikipedia link for a more complete list.  If you're a Linux user, this structure will feel familiar to you.&lt;/p&gt;

&lt;p&gt;However, even the FHS is not universal.  My personal development machine is running a super weird Linux flavor called &lt;a href="https://nixos.org/"&gt;NixOS&lt;/a&gt;.  This fully declarative system stores every single component of functionality in a unique directory called &lt;code&gt;/nix/store&lt;/code&gt; and maintains a web of symlinks.  Software compiled for standard Linux distributions won't run on NixOS or vice versa without specifically patching the resulting executable binaries.  To complicate things further, I'm pinning to the unstable channel instead of a tagged release, meaning the package set is liable to change at any time.  While there are a lot of benefits, it means my local machine is fundamentally incompatible with the Linux computers I want the software I produce to run on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Point
&lt;/h2&gt;

&lt;p&gt;I'm primarily writing code in &lt;a href="https://www.rust-lang.org/"&gt;Rust&lt;/a&gt;, which has powerful facilities for cross-compiling non-native targets built-in, and Nix can help me fill in the rest.  This is great!  From my local computer, I can produce working binaries for many different types of computers.&lt;/p&gt;

&lt;p&gt;For example, we want to support &lt;a href="https://releases.ubuntu.com/18.04/"&gt;Ubuntu 18.04&lt;/a&gt;, one &lt;a href="https://ubuntu.com/blog/what-is-an-ubuntu-lts-release"&gt;Long-Term Support&lt;/a&gt; release behind the current LTS, 20.04.  This is several years old by this point, and as a result, only has, for example, &lt;a href="https://www.gnu.org/software/libc/"&gt;&lt;code&gt;glibc&lt;/code&gt;&lt;/a&gt; version 2.27, instead of the current 2.34.  This is crucial for compatibility, because almost every program depends on your OS providing this library and being able to use whichever version it finds.&lt;/p&gt;

&lt;p&gt;However, how would I know that my result on my bleeding-edge NixOS box works as intended?  &lt;a href="https://www.docker.com/resources/what-container"&gt;Containers&lt;/a&gt; to the rescue!  We can ask &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt; to build an Ubuntu 18.04 container and drop us into a shell with the &lt;em&gt;current&lt;/em&gt; filesystem available.  It's kind of like the &lt;code&gt;su&lt;/code&gt; command, except instead of switching the active user, you're changing your whole OS on the fly.&lt;/p&gt;

&lt;p&gt;Here's the line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run --rm -it -v $PWD:/working-dir docker.io/ubuntu:18.04
root@6bb49a338644:/# cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.6 LTS"
root@487693de818e:/# cd working-dir/
root@487693de818e:/working-dir# ls
Cargo.lock  Cargo.toml  README.md  custom-target.json  dist  flake.lock  flake.nix  hello  hello_build  main.rs  scripts  target  x86_64-unknown-linux-gnu2.24.json  x86_64-unknown-linux-musldynamic.json  zig
root@7ae91a94a888:/working-dir# exit
$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect!  The &lt;code&gt;/working-dir&lt;/code&gt; directory inside your new Ubuntu 18.04 container now has the contents of whichever directory you were in when you ran this command.  That's the &lt;code&gt;-v $PWD:/working-dir&lt;/code&gt; part.  The &lt;code&gt;$PWD&lt;/code&gt; variable returns the current working directory, and after the colon, you provide a location in the new container to mount this directory.&lt;/p&gt;

&lt;p&gt;As far as any software inside is concerned, it's running in a standard Ubuntu installation.  This lets me quickly verify that my program's cross-compiled, binary-patched version runs as expected on this target environment.  When you're done, just type &lt;code&gt;exit&lt;/code&gt; to return to your native shell.  The &lt;code&gt;-it&lt;/code&gt; flag made the container interactive, and the &lt;code&gt;--rm&lt;/code&gt; flag will clean up the Docker container when it quits.&lt;/p&gt;

&lt;p&gt;You can check out the &lt;a href="https://hub.docker.com/search?category=os&amp;amp;source=verified&amp;amp;type=image"&gt;Docker Hub&lt;/a&gt; or &lt;a href="https://quay.io/"&gt;quay.io&lt;/a&gt; for other available docker containers to spin up.&lt;/p&gt;

&lt;p&gt;This tip works with any tool that supports the Docker API, in addition to Docker itself.  I'm running it via &lt;a href="https://podman.io/"&gt;Podman&lt;/a&gt;, and it works the same way.&lt;/p&gt;

&lt;p&gt;Now you can use whatever crazy environment you want and still responsibly ensure whatever you're compiling will work as intended for your users.&lt;/p&gt;

&lt;p&gt;Cover image photo by &lt;a href="https://unsplash.com/@braydona?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Braydon Anderson&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/disguise?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>linux</category>
      <category>productivity</category>
      <category>docker</category>
    </item>
    <item>
      <title>Quickly Grab Stuff From Your Git History</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Fri, 22 Oct 2021 23:30:11 +0000</pubDate>
      <link>https://forem.com/deciduously/quickly-grab-stuff-from-your-git-history-2bon</link>
      <guid>https://forem.com/deciduously/quickly-grab-stuff-from-your-git-history-2bon</guid>
      <description>&lt;p&gt;While working through a problem, my colleague remembered a prior version of our application had a syntax example we could use.  Thankfully, the codebase has been checked into &lt;a href="https://git-scm.com/"&gt;&lt;code&gt;git&lt;/code&gt;&lt;/a&gt;!  We knew the code in question revolved around the &lt;a href="https://blog.ielliott.io/nix-docs/stdenv-mkDerivation.html"&gt;&lt;code&gt;mkDerivation&lt;/code&gt;&lt;/a&gt; functionality in &lt;a href="https://nixos.org/"&gt;nix&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since then, this particular code has been moved out of our codebase and added to &lt;a href="https://github.com/NixOS/nixpkgs"&gt;&lt;code&gt;nixpkgs&lt;/code&gt;&lt;/a&gt;, so we can pull the derivation from the main tree instead of defining our own out-of-tree logic.  My first instinct was to start digging through that (huge) repository to find the file and use that as a reference.&lt;/p&gt;

&lt;p&gt;No need!  We have it in our &lt;code&gt;git&lt;/code&gt; history.  We can query this using &lt;code&gt;git log -S&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git log -S mkDerivation
commit 3a275488e740ae1b4314208a908c5300f9563ee0
Author: David Yamnitsky &amp;lt;david@yamnitsky.com&amp;gt;
Date:   Mon Jul 19 11:51:47 2021 -0400

    use mold and wasm-bindgen from nixpkgs

commit a3a042b5b90ad57ff11bc47a5db6e68dc1ca55e7
Author: David Yamnitsky &amp;lt;david@yamnitsky.com&amp;gt;
Date:   Wed Jun 16 10:26:35 2021 -0400

    use mold as the linker to speed up incremental compiles on x86_64-linux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beautiful - that top commit looks like it represents when we switched to pull this derivation directly from &lt;code&gt;nixpkgs&lt;/code&gt;.  Removing the code is sufficient - each &lt;code&gt;git&lt;/code&gt; commit represents a diff.  This commit should show us the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git show 3a275488e740ae1b4314208a908c5300f9563ee0
commit 3a275488e740ae1b4314208a908c5300f9563ee0
Author: David Yamnitsky &amp;lt;david@yamnitsky.com&amp;gt;
Date:   Mon Jul 19 11:51:47 2021 -0400

    use mold and wasm-bindgen from nixpkgs
...
flake. nix

───┐
1: │
───┘
{
  inputs = {
    nixpkgs = {
      url = "github:nixos/nixpkgs/nixos-unstable";
      url = "github:nixos/nixpkgs/nixos-unstable-small";
    };
    flake-utils = {
      url = "github:numtide/flake-utils";

────┐
48: │
────┘
        CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER = toString ./. + "/scripts/clang";
        CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_LINKER = "lld";
        buildInputs = with pkgs; [
          (stdenv.mkDerivation {
            pname = "mold";
            version = "0.9.1";
            src = fetchgit {
              url = "https://github.com/rui314/mold";
              rev = "v0.9.1";
              sha256 = "sha256-yIkW6OCXhlHZ1jC8/yMAdJbSgY9K40POT2zWv6wYr5E=";
            };
            nativeBuildInputs = [ clang_12 cmake lld_12 tbb xxHash zlib openssl git ];
            dontUseCmakeConfigure = "true";
            buildPhase = "make -j $NIX_BUILD_CORES";
            installPhase = "mkdir -p $out $out/bin $out/share/man/man1 &amp;amp;&amp;amp; PREFIX=$out make install";
          })
          cachix
          cargo-insta
          clang_12

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There it is, in the text!  In my terminal, additions are highlighted in green and removals are in red.  This was a removal, but you still get the full removed text.  I was able to copy that &lt;code&gt;stdenv.mkDerivation&lt;/code&gt; code and work from there.  Thanks, &lt;code&gt;git&lt;/code&gt;.  (Thit).&lt;/p&gt;

&lt;p&gt;As an aside, I highly recommend the following &lt;code&gt;git&lt;/code&gt; alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;l = "log --all --graph --decorate --abbrev-commit --format=format:'%C(bold blue)%h%C(reset) - %C(bold white)%an%C(reset) %C(bold yellow)%d%C(reset)%n%C(bold cyan)%aD%C(reset) - %C(bold green)(%ar)%C(reset)%n%C(white)%s%C(reset)'";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a mess of text, but it produces super easy to read git histories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* 9b24232 - Ben Lovy  (HEAD -&amp;gt; main, origin/main, origin/HEAD)
| Fri, 22 Oct 2021 11:49:42 -0400 - (8 hours ago)
| Remove maplit
* 65016b6 - David Yamnitsky 
| Fri, 22 Oct 2021 11:39:12 -0400 - (8 hours ago)
| update deps
| * 6d55d3e - Ben Lovy  (refs/stash)
|/| Fri, 22 Oct 2021 11:49:01 -0400 - (8 hours ago)
| | WIP on main: e07e691 clear 1.56 warnings
| * 6bf8ab1 - Ben Lovy 
|/  Fri, 22 Oct 2021 11:49:01 -0400 - (8 hours ago)
|   index on main: e07e691 clear 1.56 warnings
* e07e691 - David Yamnitsky 
| Fri, 22 Oct 2021 11:09:02 -0400 - (8 hours ago)
| clear 1.56 warnings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The coloration doesn't reflect here, in your terminal this will be &lt;em&gt;even cooler&lt;/em&gt;.  As a &lt;code&gt;git&lt;/code&gt; novice, this sort of output is instrumental in keeping track of changes to the codebase.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>git</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Rust Function Pointers Across FFI Boundary</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Fri, 10 Sep 2021 13:39:40 +0000</pubDate>
      <link>https://forem.com/deciduously/rust-function-pointers-across-ffi-boundary-egg</link>
      <guid>https://forem.com/deciduously/rust-function-pointers-across-ffi-boundary-egg</guid>
      <description>&lt;p&gt;Hi DEV - it's been ages!  I'm stumped on a problem, and remembered my old adage: "ask DEV stuff, they know things".  So, here's hoping someone can unstick me!&lt;/p&gt;

&lt;p&gt;EDIT:  Figured it out.  Left the solution in the comments!&lt;/p&gt;

&lt;p&gt;I'm trying to store a pointer to a function defined in C in a Rust struct, and call it from the Rust side. The rest of my FFI seems to be hooked up okay, but I'm getting a segfault when I make the actual function call. Debugging sessions have not proved useful.&lt;/p&gt;

&lt;p&gt;I'll try to keep the context streamlined, but let me know if you need more to see what's going on.&lt;/p&gt;

&lt;p&gt;First, here's the C externs, the function I'm pointing to, and the passage across the FFI boundary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="n"&gt;scheduler_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="n"&gt;job_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="nf"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;unit_to_unit_t&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scheduler_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit_to_unit_t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;job_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;job_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Define a job&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;job&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//printf("Hello!  It is now %s\n", now());&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Super exciting stuff. The commented out line calls a &lt;code&gt;now()&lt;/code&gt;function that returns a &lt;code&gt;char *&lt;/code&gt;, but I wanted to get anything working first. The &lt;code&gt;every()&lt;/code&gt; function returns &lt;code&gt;job_t *&lt;/code&gt;, and &lt;code&gt;seconds()&lt;/code&gt; takes a &lt;code&gt;job_t *&lt;/code&gt; and returns a &lt;code&gt;job_t *&lt;/code&gt;, which is finally passed into &lt;code&gt;run()&lt;/code&gt;. I have a typedef named &lt;code&gt;unit_to_unit_t&lt;/code&gt; for the job function pointer - it's a function taking no arguments and returning nothing. The scheduler is also an FFI entity.&lt;/p&gt;

&lt;p&gt;This is the definition of &lt;code&gt;run()&lt;/code&gt; on the Rust side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Job&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Scheduler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="nf"&gt;.is_null&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="nf"&gt;.is_null&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="nf"&gt;.is_null&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;*&lt;/span&gt;&lt;span class="n"&gt;work&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="nf"&gt;.run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap_or_else&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm passing the C function as the last argument here, and trying to cast it to &lt;code&gt;work&lt;/code&gt;. This step doesn't complain, seems to go okay.&lt;/p&gt;

&lt;p&gt;On the Rust side, when that &lt;code&gt;job.run()&lt;/code&gt; method gets called, the following trait/struct is used to store the function pointer and call it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;Callable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/// Execute this callable&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="cd"&gt;/// Get the name of this callable&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/// A named callable function taking no parameters and returning nothing.&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;UnitToUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;UnitToUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Callable&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;UnitToUnit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// gets HERE just fine...&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.work&lt;/span&gt;&lt;span class="p"&gt;)();&lt;/span&gt;
        &lt;span class="nb"&gt;None&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This all works fine with Rust function pointers. I determined that with the C version, we do get inside the &lt;code&gt;call()&lt;/code&gt; implementation - the segfault happens when I use &lt;code&gt;(self.work)();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I'm not sure if it's relevant, but the actual call is triggered here in C:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run_pending&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scheduler_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    

&lt;span class="c1"&gt;// Run some jobs&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;run_pending&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which corresponds to this Rust interface fn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;run_pending&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Scheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="nf"&gt;.is_null&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="n"&gt;scheduler&lt;/span&gt;
        &lt;span class="nf"&gt;.run_pending&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap_or_else&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's &lt;code&gt;scheduler::run_pending()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="cd"&gt;/// Run all jobs that are scheduled to run.  Does NOT run missed jobs!&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;run_pending&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//let mut jobs_to_run: Vec&amp;lt;&amp;amp;Job&amp;gt; = self.jobs.iter().filter(|el| el.should_run()).collect();&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.jobs&lt;/span&gt;&lt;span class="nf"&gt;.sort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;to_remove&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.jobs&lt;/span&gt;&lt;span class="nf"&gt;.iter_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="nf"&gt;.should_run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;keep_going&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="nf"&gt;.execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;keep_going&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cancelling job {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;to_remove&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// Remove any cancelled jobs&lt;/span&gt;
        &lt;span class="n"&gt;to_remove&lt;/span&gt;&lt;span class="nf"&gt;.sort_unstable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;to_remove&lt;/span&gt;&lt;span class="nf"&gt;.reverse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;to_remove&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.jobs&lt;/span&gt;&lt;span class="nf"&gt;.remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, &lt;code&gt;job::execute()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="cd"&gt;/// Run this job and immediately reschedule it, returning true.  If job should cancel, return false.&lt;/span&gt;
    &lt;span class="cd"&gt;///&lt;/span&gt;
    &lt;span class="cd"&gt;/// If the job's deadline has arrived already, the job does not run and returns false.&lt;/span&gt;
    &lt;span class="cd"&gt;///&lt;/span&gt;
    &lt;span class="cd"&gt;/// If this execution causes the deadline to reach, it will run once and then return false.&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.is_overdue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deadline already reached, cancelling job {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running job {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.job&lt;/span&gt;&lt;span class="nf"&gt;.is_none&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No work scheduled, moving on..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.job&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.call&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// CALLED RIGHT HERE&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.last_run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.now&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.schedule_next_run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.is_overdue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Execution went over deadline, cancelling job {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added a comment where the actual &lt;code&gt;call()&lt;/code&gt; happens.&lt;/p&gt;

&lt;p&gt;This whole FFI shindig is just an experiment, I don't actually have a real need for this to work - but now that I got this far, I kinda want to know what I'm getting wrong! Thanks in advance.&lt;/p&gt;

</description>
      <category>help</category>
      <category>rust</category>
      <category>c</category>
      <category>ffi</category>
    </item>
    <item>
      <title>Using Bitwise Operators: Why Waste Space Use Many Bits When Few Bits Do Trick?</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Sun, 09 Aug 2020 20:06:27 +0000</pubDate>
      <link>https://forem.com/deciduously/using-bitwise-operators-why-waste-space-use-many-bits-when-few-bits-do-trick-2ap6</link>
      <guid>https://forem.com/deciduously/using-bitwise-operators-why-waste-space-use-many-bits-when-few-bits-do-trick-2ap6</guid>
      <description>&lt;p&gt;These days, we live in the future.  Memory is very cheap.  When we need to store an integer, in most cases it makes sense to just use an entire multi-byte value to represent it even if your value is low.  Of course, that does result in a lot of wasted space.  The number &lt;code&gt;2&lt;/code&gt; as a 32-bit integer looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just one of these bits is flipped towards the end - all the rest is just padding.&lt;/p&gt;

&lt;p&gt;I'm working on a &lt;a href="https://en.wikipedia.org/wiki/CHIP-8"&gt;Chip8&lt;/a&gt; emulator.  To build such an emulator, you create a software representation of the entire computer.  It has a space for the program memory, some registers for short-term storage, some counters, some boolean flags - everything it needs to execute a program.&lt;/p&gt;

&lt;p&gt;The Chip8 is a much more limited environment than a modern computer.  The entire space for memory only comprises 4096 bytes - and some of that is reserved for the system itself.  With such a constraint it doesn't make sense to waste all this space.  Whenever possible we want to concern ourselves with a single byte at a time, so that surrounding bytes can be meaningfully applied to other parts of the program.&lt;/p&gt;

&lt;p&gt;In fact, as we'll see, we don't even need to limit ourselves to a byte.  Using bitwise operators we can efficiently use individual bits within a byte to store and communicate information with minimal wasted space.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Machine
&lt;/h2&gt;

&lt;p&gt;I'm doing mine in Rust, but you don't need to know Rust to follow this post.  This is what my struct representing the machine looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="cd"&gt;/// The top-level software representation of the Chip8 machine&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Machine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;opcode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cd"&gt;/// Available memory space - 4K&lt;/span&gt;
    &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="cd"&gt;/// CPU Registers&lt;/span&gt;
    &lt;span class="n"&gt;registers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="cd"&gt;/// Index register&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cd"&gt;/// Program counter&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;pc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cd"&gt;/// Graphics system - 2048 total pixels, arranged 64x32, each containing 0 or 1&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="cd"&gt;/// Delay timer - 60Hz, counts down if above 0&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;delay_timer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cd"&gt;/// Sound timer - buzzes at 0.  60Hz, counts down if above 0&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;sound_timer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cd"&gt;/// Call stack&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="cd"&gt;/// Stack pointer&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cd"&gt;/// Keep track of the keypad - 0x0-0xF&lt;/span&gt;
    &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="cd"&gt;/// Flag to signal the screen state has changed and must be redrawn&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;draw_flag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The biggest thing you need to know is that a &lt;code&gt;u8&lt;/code&gt; is an unsigned 8-bit value, or a single byte, and a &lt;code&gt;u16&lt;/code&gt; is an unsigned 16-bit value.  The &lt;code&gt;usize&lt;/code&gt; types are machine-dependent pointer-sized values, used to index into arrays.  In my case they're analogous to &lt;code&gt;u64&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There is a software representation for each part of the computer a program will interact with.  Then, you can programmatically hook up actual inputs and outputs however you like, and the running program is none the wiser.  Inside this struct everything works exactly as it would on a physical version of this machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hexadecimal Representation
&lt;/h2&gt;

&lt;p&gt;When working with individual bytes hexadecimal is much more convenient than decimal.  A single hexadecimal digit maps neatly to a 4-bit value, or a &lt;em&gt;nibble&lt;/em&gt;, and thus can express every possible configuration of 4 bits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0x0 -&amp;gt; 0 0 0 0
0x1 -&amp;gt; 0 0 0 1
0x2 -&amp;gt; 0 0 1 0
0x3 -&amp;gt; 0 0 1 1
0x4 -&amp;gt; 0 1 0 0
0x5 -&amp;gt; 0 1 0 1
0x6 -&amp;gt; 0 1 1 0
0x7 -&amp;gt; 0 1 1 1
0x8 -&amp;gt; 1 0 0 0
0x9 -&amp;gt; 1 0 0 1
0xA -&amp;gt; 1 0 1 0
0xB -&amp;gt; 1 0 1 1
0xC -&amp;gt; 1 1 0 0
0xD -&amp;gt; 1 1 0 1
0xE -&amp;gt; 1 1 1 0
0xF -&amp;gt; 1 1 1 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's clear to see the pattern.  This makes hexadecimal a natural way to talk about memory in such small quantities.  A byte is 8 bits, which is two nibbles next to each other.  Using two hex digits we can represent every possible byte from &lt;code&gt;0x00&lt;/code&gt;, which is all 8 zeros, to &lt;code&gt;0xFF&lt;/code&gt;, which is all 8 ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Opcodes
&lt;/h2&gt;

&lt;p&gt;To interact with the machine state, a program consists of a series of opcodes.  Each cycle, the machine reads the current opcode and then updates the state in memory and registers according to which specific instruction is found.  When the program loads these opcodes are copied into the computer's memory sequentially, beginning at the starting address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="cd"&gt;/// Locate a program file by filename and load into memory.  Returns total bytes loaded.&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;load_game&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Clear the memory to make way&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SHELF&lt;/span&gt;&lt;span class="nf"&gt;.rom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// I have all game data pre-loaded in memory and tagged by name&lt;/span&gt;
    &lt;span class="c1"&gt;// Load in memory starting at location 512 (0x200), which is where the pc pointer starts&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rom&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.memory_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.pc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rom&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It all just gets copied one byte at a time, and the &lt;code&gt;self.pc&lt;/code&gt; pointer is used to keep track of where the machine is currently looking.  However, each instruction is actually more than a single byte long.  There is a &lt;a href="https://en.wikipedia.org/wiki/CHIP-8#Opcode_table"&gt;full list&lt;/a&gt; on Wikipedia, 35 in total.  Here's a few examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1NNN -&amp;gt; Jump to address NNN
8XY4 -&amp;gt; Add the value in register Y to the value in register X
3XNN -&amp;gt; Skip the next instruction if the value in register X equals 0xNN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of these digits is hexadecimal so each opcode is 2 bytes long, or 16 bits.  In Rust, I use the &lt;code&gt;u16&lt;/code&gt; datatype to work with these numbers.  Further, each one carries different amounts of information.  There is a hardcoded prefix and/or suffix to determine which exact instruction, and then within that various nibbles are used to denote different things.  Look at the differences between these codes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0x1234 -&amp;gt; Jump to address 0x234
     1       2         3        4
0 0 0 1 | 0 0 1 0 | 0 0 1 1 | 0 1 0 0 

Extract value 0x234 - pad to 0x0234
0 0 0 0 0 0 1 0 0 0 1 1 0 1 0 0
___

0x8234 -&amp;gt; Add the value in register 3 to the current value in Register 2
    8       2         3        4
1 0 0 0 | 0 0 1 0 | 0 0 1 1 | 0 1 0 0 

Extract values 0x2 and 0x3
0 0 1 0
0 0 1 1

___

0x3234 -&amp;gt; Skip the next instruction if the value in register 2 equals 0x34
    3       2         3        4
0 0 1 1 | 0 0 1 0 | 0 0 1 1 | 0 1 0 0

Extract values 0x2 and 0x34
0 0 1 0
0 0 1 1 0 1 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only difference in bit-level representation between 0x1234 and 0x8234 is which bit is flipped in the first nibble.  However, the information stored is not used in the same way.  To successfully address all 4096 memory locations a single byte is insufficient, but 12 bits is enough, so we pull the final three nibbles and understand them as a single number.  To specify registers, though, there's only 16 of those - we don't need all the extra space.  A single nibble is enough to uniquely address any of the registers.  Thus, the second and third nibbles are used to specify the targets and the final nibble is simply used as another hard-coded opcode designator.  The &lt;code&gt;3XNN&lt;/code&gt; code uses a third pattern, extracting two values but one is a nibble and the other is a full byte.  It skips an instruction of the value at register X is equal to the value in NN.&lt;/p&gt;

&lt;p&gt;The point is that while specific patterns of bits may be the same or similar, how they're understood within the program can vary.  There's a lot of different ways to efficiently utilize a pattern of 16 bits depending on how many total possibilities there are for each unit of information.  This means that you can't approach an opcode as a single number or even two separate bytes.  It's really four nibbles, and what you do with them will depend on the specific opcode.  It makes most sense to work with these as a pattern of individual bits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bitwise Manipulation
&lt;/h2&gt;

&lt;p&gt;Bitwise operators look at the individual bits in each operand to produce a result, instead of dealing at the higher abstraction level that "numbers" introduce.  We'll look at &lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;, and &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;, with some passing mention of &lt;code&gt;^&lt;/code&gt; as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extract Specific Nibbles
&lt;/h3&gt;

&lt;p&gt;The first example was &lt;code&gt;1NNN&lt;/code&gt;.  The relevant information the machine needs to execute this opcode consists of the last three nibbles of the opcode.  After we have determined that &lt;code&gt;0x1234&lt;/code&gt; is an opcode of this type, all we need to do is grab that &lt;code&gt;0x234&lt;/code&gt; value.  To do this you can use the bitwise &lt;code&gt;&amp;amp;&lt;/code&gt;, or AND:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AND
A  B  Result

0  0  0
1  0  0
0  1  0
1  1  1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;AND&lt;/code&gt; operation checks if both values are set to &lt;code&gt;1&lt;/code&gt;, or &lt;code&gt;true&lt;/code&gt;.  If they are, &lt;code&gt;A &amp;amp; B = 1&lt;/code&gt;.  If they aren't both set, the result is &lt;code&gt;0&lt;/code&gt;, or &lt;code&gt;false&lt;/code&gt;.  We can use this to find the set bits of only a portion of a 16-bit value.  If we take &lt;code&gt;0x1234 &amp;amp; 0x0FFF&lt;/code&gt;, the result will contain the exact bits that are set in the last three nibbles and completely ignore the first nibble:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0x1234 -&amp;gt; 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0
0x0FFF -&amp;gt; 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
&amp;amp;        ________________________________
0x0234 -&amp;gt; 0 0 0 0 0 0 1 0 0 0 1 1 0 1 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By applying the AND rules to each pair of bits in sequence, the final total has only zeros for the not-relevant first nibble and successfully retains the information from the rest of the first byte.  We now have a bit pattern that fits neatly into a &lt;code&gt;u16&lt;/code&gt; containing the extracted information.&lt;/p&gt;

&lt;p&gt;We can use the same logic to grab, for instance, the last byte, like we do to pull &lt;code&gt;0x34&lt;/code&gt; from &lt;code&gt;0x3234&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0x3234 -&amp;gt; 0 0 1 1 0 0 1 0 0 0 1 1 0 1 0 0
0x00FF -&amp;gt; 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
&amp;amp;        ________________________________
0x0034 -&amp;gt; 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;last_three_digits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;0x0FFF&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's important to note once again that this neat mapping of place value to nibble &lt;em&gt;only&lt;/em&gt; works with hexadecimal - &lt;code&gt;0x34&lt;/code&gt; in base 16 is &lt;code&gt;52&lt;/code&gt; in base 10!  It's easy to get confused.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extract Any Nibble
&lt;/h3&gt;

&lt;p&gt;As an extension of the previous concept, many of these opcodes require extracting just the second and/or third nibble, which in memory are actually stored in consecutive bytes.  To get the second you can use &lt;code&gt;0x0F00&lt;/code&gt;, or &lt;code&gt;0x00F0&lt;/code&gt; for the third.&lt;/p&gt;

&lt;p&gt;You &lt;em&gt;could&lt;/em&gt; write a separate function for each position, but it's not hard to use bit-shifting to generalize it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;nibble_from_left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;from_most&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Make sure the parameter is legal&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;from_most&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"cannot get the {}th nibble from 2-byte number {:#0x}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;from_most&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;from_most&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;0xF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's use this function to grab the &lt;code&gt;0x2&lt;/code&gt; from &lt;code&gt;0x8234&lt;/code&gt;.  This function expects the index from the most-significant digit, or the left, starting at 0, so to get at the second nibble the index passed as a parameter will be &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, we can observe that anything less significant - or to the right - of the nibble in question is totally irrelevant.  We can discard it completely.  We are only interested in a &lt;em&gt;single&lt;/em&gt; nibble, which means that running our bitwise &lt;code&gt;&amp;amp;&lt;/code&gt; operator against just &lt;code&gt;0xF&lt;/code&gt; will be sufficient to pull what we need and discard anything before it.  By using the &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;, or right-shift operator, we can move the nibble in question right to the end of the number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0x8234 -&amp;gt; 1 0 0 0 0 0 1 0 0 0 1 1 0 1 0 0
&amp;gt;&amp;gt; 8
0x0082 -&amp;gt; 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shifting right by one discard the rightmost bit, pads a new 0 bit to the left, and moves everything over.  If we do this eight times we've discarded the last two nibbles and moved the one we're interested in right to the end.  Now we can run the &lt;code&gt;&amp;amp;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0x0082 -&amp;gt; 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0
0xF    -&amp;gt; 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
&amp;amp;      ___________________________________
0x0002    0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Brilliant!  Using &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;amp;&lt;/code&gt;, we were able to produce a bit pattern that corresponds to the exact digit we need.  The missing piece was how much to shift right - &lt;code&gt;4 * (3 - from_most);&lt;/code&gt; means that we will always shift bits by a multiple of 4 to always deal with a whole nibble at a time.  We just need to know how many nibbles to shift.  To get the 3rd least significant digit, like this case, we take &lt;code&gt;4 * (3 - 1) = 4 * 2 = 8&lt;/code&gt;.  This way we can reuse the same logic to pull any of the four nibbles out.  The only thing that changes is how much data at the end we discard - if we want the last nibble after all, this would be &lt;code&gt;4 * (3 - 3) = 0&lt;/code&gt;, and applying &lt;code&gt;&amp;gt;&amp;gt; 0&lt;/code&gt; to a number will leave it as-is.&lt;/p&gt;

&lt;p&gt;This is used very commonly to parse the opcodes used in the Chip8 machine.  Many of them specifically carry information in the middle two nibbles so I just made a helper function to pull those:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;middle_nibbles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.nibble_from_left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.nibble_from_left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will very neatly return &lt;code&gt;(0x2, 0x3)&lt;/code&gt; when called on &lt;code&gt;0x8234&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combine Bytes
&lt;/h3&gt;

&lt;p&gt;When we loaded the program - or series of opcodes - into memory, we copied them one single byte at a time.  This means that each opcode is occupying two adjacent memory locations.  We need to wrap them up together and understand that sequence of 16 consecutive bits as a single number.  In other words, we need to find the &lt;code&gt;u16&lt;/code&gt; you get when you place two &lt;code&gt;u8&lt;/code&gt; values next to each other.  If you have the bytes &lt;code&gt;0xAB&lt;/code&gt; and &lt;code&gt;0xCD&lt;/code&gt;, how do you produce the 16-bit value &lt;code&gt;0xABCD&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;On paper, we can visually see the solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0xAB   -&amp;gt; 1 0 1 0 1 0 1 1
0xCD   -&amp;gt;                 1 1 0 0 1 1 0 1
0xABCD -&amp;gt; 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You just need to grab a space big enough and put the more significant byte to the left of the less significant byte.  Of course, we have to get there with bitwise operators, though, lacking an in-software pencil and paper.&lt;/p&gt;

&lt;p&gt;To isolate a nibble from a longer bit sequence, we used the right-shift &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; above to shift the nibble we need to the end.  The reverse left-shift operation &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; also exists, which will discard more significant digits to the left and pad with zeros on the right.  If we shift left by 8 bits we will essentially insert a blank byte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0xAB   -&amp;gt; 1 0 1 0 1 0 1 1
&amp;lt;&amp;lt; 8
0xAB00 -&amp;gt; 1 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great!  To pop our actual intended second byte in, we can use bitwise &lt;code&gt;OR&lt;/code&gt;, or &lt;code&gt;|&lt;/code&gt;.  This has a similar function to &lt;code&gt;AND&lt;/code&gt; but with the following truth table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OR
A  B  Result

0  0  0
1  0  1
0  1  1
1  1  1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is that this operator returns &lt;code&gt;true&lt;/code&gt;/&lt;code&gt;1&lt;/code&gt; if &lt;em&gt;either&lt;/em&gt; of the operands is set to &lt;code&gt;1&lt;/code&gt;. It's only false if both bits are false.  We can use this to combine our newly-expanded first byte with the intended second byte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0xAB00 -&amp;gt; 1 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0
0xCD   -&amp;gt; 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1
|       _________________________________
0xABCD -&amp;gt; 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This operation just pulls down whatever is relevant from either byte, effectively combining them.  So, first, shift the more significant byte, then OR it against the less significant byte to pull out your single 16-bit value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;combine_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte_one&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;byte_two&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte_one&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;byte_two&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the emulator emulates a cycle it reads two bytes starting at the current program counter and combines them using this method to understand the current opcode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;fetch_opcode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Opcode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first_byte&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.current_byte&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;second_byte&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.memory_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.pc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;second_byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my implementation the &lt;code&gt;Opcode::new()&lt;/code&gt; logic contains the call to this internal &lt;code&gt;combine_bytes&lt;/code&gt; method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Misc
&lt;/h3&gt;

&lt;p&gt;These are the bitwise operations I've used in handling Chip8 opcodes, but understanding these operators can lead to some very efficient implementations of some other commonly needed operations.&lt;/p&gt;

&lt;h4&gt;
  
  
  Even or Odd
&lt;/h4&gt;

&lt;p&gt;One handy one to keep under your belt is to check whether a given number is even or odd.  A common idiom many of us reach for is the modulo operator: &lt;code&gt;byte % 2 == 0&lt;/code&gt;.  If the remainder after dividing by two is 0 then it's an even number.&lt;/p&gt;

&lt;p&gt;There's actually two ways (that I know) to do this.  We went over bitwise AND in this article, so I'll cover that - it's similar to the trick we used to extract a nibble.  In a binary representation of a number, all we need to determine whether a number is even is the very last bit.  If it's even, this will be a zero, and if it's odd, this will be a one.  If that observation isn't intuitive, go &lt;a href="https://dev.to/deciduously/using-bitwise-operators-why-waste-space-use-many-bits-when-few-bits-do-trick-2ap6#hexadecimal-representation"&gt;back up&lt;/a&gt; and look at the mappings from hex digits to nibbles and see if you can see why this is true.&lt;/p&gt;

&lt;p&gt;This means that it's sufficient to AND your value against &lt;code&gt;1&lt;/code&gt;.  You will get back a 1 if the value to check ends in a 1 bit, or a 0 if it's zero.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5 -&amp;gt; 0 1 0 1
1 -&amp;gt; 0 0 0 1
&amp;amp;  _________
1 -&amp;gt; 0 0 0 1

___

6 -&amp;gt; 0 1 1 0
1 -&amp;gt; 0 0 0 1
&amp;amp;  _________
0 -&amp;gt; 0 0 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, just check what you got.  If the bit was set, it's an odd number, otherwise, it's even.  In Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;is_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will work on values of any size, because it only ever looks at the least significant bit.&lt;/p&gt;

&lt;p&gt;While in most applications the performance benefit is likely negligible, this solution will be more efficient than using &lt;code&gt;%&lt;/code&gt;.  In some situations it may be enough to prefer this.&lt;/p&gt;

&lt;p&gt;I'll leave the other solution I know as an exercise - can you do it using bitwise XOR (exclusive-or)?  This operator looks like &lt;code&gt;^&lt;/code&gt; in many languages.  Here's the truth table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XOR
A  B  Result

0  0  0
1  0  1
0  1  1
1  1  0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;^&lt;/code&gt;/&lt;code&gt;XOR&lt;/code&gt; operation is similar to &lt;code&gt;|&lt;/code&gt;/&lt;code&gt;OR&lt;/code&gt;, but only returns true if one or the other bit is set and &lt;em&gt;not&lt;/em&gt; both.  Show me what you get in the comments!&lt;/p&gt;

&lt;h4&gt;
  
  
  Double/Halve Numbers
&lt;/h4&gt;

&lt;p&gt;The left and right shift operations we used above are super handy.  When you push the bits in a binary number to the left, you end up doubling the value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6  -&amp;gt; 0 1 1 0
&amp;lt;&amp;lt; 1
12 -&amp;gt; 1 1 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking at the above it's clear to see that this will work the other way, too.  Shifting right instead will undo the above, effectively halving the value.   You can extend this to any power of two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6  -&amp;gt; 0 0 1 1 0

&amp;lt;&amp;lt; 2
24 -&amp;gt; 1 1 0 0 0

&amp;lt;&amp;lt; 3
48 -&amp;gt; 1 1 0 0 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shifting right by n is the same thing as multiplying by 2^n.  Neat!  As with the even/odd trick, this will probably be more efficient than multiplying - however, you do lose some readability.  As with any optimization, it always depends on context.&lt;/p&gt;

&lt;p&gt;There are numerous other bitwise "hacks" like this.  Share some of your favorites below!&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgements
&lt;/h2&gt;

&lt;p&gt;If you're going to tackle your own Chip8 emulator, while the Wikipedia page has a lot of what you need, I also recommend &lt;a href="http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter/"&gt;How to write an emulator&lt;/a&gt; by &lt;a href="http://www.multigesture.net/about/"&gt;Laurence Muller&lt;/a&gt;.  So far, this blog post and Wikipedia have been the only two resources I've needed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover image: Photo by &lt;a href="https://unsplash.com/@fedechanw?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Federica Galli&lt;/a&gt; on &lt;a href="https://unsplash.com/"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>devjournal</category>
      <category>chip8</category>
    </item>
    <item>
      <title>Prime Sieve in (Hopefully) Idiomatic Ruby (And Some Books You Should Read)</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Thu, 06 Aug 2020 04:14:49 +0000</pubDate>
      <link>https://forem.com/deciduously/prime-sieve-in-hopefully-idiomatic-ruby-and-some-books-you-should-read-5ed1</link>
      <guid>https://forem.com/deciduously/prime-sieve-in-hopefully-idiomatic-ruby-and-some-books-you-should-read-5ed1</guid>
      <description>&lt;p&gt;Hey y'all.  Been awhile.  Books are at the bottom.&lt;/p&gt;

&lt;p&gt;Earlier this week, I got my first "star" on an &lt;a href="https://exercism.io"&gt;exercism.io&lt;/a&gt; for a solution very early on in the Ruby track I wrote months ago, so I went back and looked at what I wrote.  I'm far enough removed from writing this solution that reading the code was interesting, and I can tell I was largely eager to flex all the cool toys I just learned.  So, I want to tell you what I did, and I want you to tell me how you'd do it better.&lt;/p&gt;

&lt;p&gt;The problem is the &lt;a href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;Sieve of Eratosthenes&lt;/a&gt;.  I did say it was an early one, but I'd argue problems that are easy to wrap your head around are the best way to flex in a new environment.  That's "era-TOSS-the-knees", if you're like me and read it way before you heard it or said it.  Basically, you can find prime numbers up to &lt;code&gt;n&lt;/code&gt; by going up a number list one by one, calling each element &lt;code&gt;x&lt;/code&gt; and crossing out all numbers from &lt;code&gt;x&lt;/code&gt; up to &lt;code&gt;n&lt;/code&gt; that are a multiple of &lt;code&gt;x&lt;/code&gt;.  If it's a multiple of something, it's not prime.  Eventually, the list remaining comprises all the primes from &lt;code&gt;2&lt;/code&gt; to &lt;code&gt;n&lt;/code&gt;.  Easy enough.&lt;/p&gt;

&lt;p&gt;What's neat, though, is that in Ruby you can kinda just say that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Sieve of Eratosthenes&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sieve&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@all&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_a&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;primes&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="vi"&gt;@all&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;

    &lt;span class="vi"&gt;@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="vi"&gt;@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="vi"&gt;@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;zero?&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="vi"&gt;@all&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first thing you learn when learning Ruby is how deeply Object-Oriented Programming permeates its design.  Instead of thinking in terms of calling methods and executing functions, which a fundamentally imperative way of approaching a task, it's important to try to shift towards "passing messages" and receiving responses.  The biggest thing I've learned is that design is not so much about the classes you have, it's about how they interface with each other and the messages they can utilize.&lt;/p&gt;

&lt;p&gt;Ruby is an idiosyncratic language in that many of its idioms arise from the wealth of messages that are available to pass.  Instead of checking if &lt;code&gt;2 == 0&lt;/code&gt;, you pass the object &lt;code&gt;2&lt;/code&gt; - which is an instance of class &lt;code&gt;Integer&lt;/code&gt; - the message &lt;code&gt;zero?&lt;/code&gt; and see what it says.  Quite often, I fire up &lt;a href="https://pry.github.io/"&gt;&lt;code&gt;pry&lt;/code&gt;&lt;/a&gt; and enter questions like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grep&lt;/span&gt; &lt;span class="sr"&gt;/z/&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:rationalize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:zero?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:nonzero?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:frozen?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:freeze&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool.  That's all the methods that the number &lt;code&gt;2&lt;/code&gt; knows how to respond to that contain the letter &lt;code&gt;z&lt;/code&gt;.  Why?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right.  Any &lt;code&gt;Integer&lt;/code&gt; can.  But it goes deeper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Numeric&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;BasicObject&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's &lt;code&gt;BasicObject&lt;/code&gt;s &lt;a href="https://en.wikipedia.org/wiki/Turtles_all_the_way_down"&gt;all the way down&lt;/a&gt;.  If you pass a message to an object, it will first check the object itself for an implementation.  If it isn't found, it will then check the &lt;code&gt;class&lt;/code&gt; for the implementation (or "go right").  If that class doesn't have it, it will check superclasses (or "go up") until it finds what it needs, or doesn't.  Right one, then up until a match or &lt;code&gt;nil&lt;/code&gt;.  Easy enough.  Even &lt;code&gt;Class&lt;/code&gt; is a class (it subclasses &lt;code&gt;Module&lt;/code&gt;), you can call methods on it like &lt;code&gt;attr_reader&lt;/code&gt;.  You often see it without parens (&lt;code&gt;attr_reader :name, :address, :email&lt;/code&gt;), but Ruby doesn't require parentheses for method calls.  It's all "just Ruby".  Whoa.  I highly recommend &lt;a href="https://pragprog.com/titles/ppmetr2/"&gt;Metaprogramming Ruby 2&lt;/a&gt; for grokking the significance of all this.&lt;/p&gt;

&lt;p&gt;This high degree of runtime reflection is part of what makes Ruby, well, Ruby.  All this to say that the &lt;code&gt;Integer&lt;/code&gt; class implements the &lt;code&gt;zero?&lt;/code&gt; method. The visual leap from &lt;code&gt;2 == 0&lt;/code&gt; to &lt;code&gt;2.zero?&lt;/code&gt; isn't huge, but the conceptual leap is important.  I am working with a bunch of objects living in memory, and I can ask any of them fairly complex questions about themselves.  Coming from C++ and Rust, where by the time your code executes it's already just "some machine code at some address", it's a big shift in how you understand and work with a running application.  I'm used to writing my own abstractions this way, but not necessarily interacting with the language itself like this.&lt;/p&gt;

&lt;p&gt;Which brings me back to the code.  To start off with the sieve, I populate an instance variable &lt;code&gt;@all&lt;/code&gt; in the class constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@all&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_a&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When executing the sieve, you have an upper limit for the primes you want to calculate, and this is passed to the constructor as &lt;code&gt;n&lt;/code&gt;.  I used the tertiary conditional operator to ask if this upper limit is greater than 1.  If it isn't, there's no primes to report, so the fallback at the end is an empty list &lt;code&gt;[]&lt;/code&gt;.  However, most invocations will pass a larger integer, in which case &lt;code&gt;@all&lt;/code&gt; gets instantiated with &lt;code&gt;2.upto(n).to_a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another super idiosyncratic thing about Ruby is how pervasive &lt;a href="https://ruby-doc.org/core-2.7.1/Enumerator.html"&gt;&lt;code&gt;Enumerator&lt;/code&gt;&lt;/a&gt; is.  I find this tendency seeping into the all the code I write, which is why I love learning different types of languages.  The first message we pass &lt;code&gt;2&lt;/code&gt; is &lt;code&gt;upto(n)&lt;/code&gt;.  This returns an &lt;code&gt;Enumerator&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;Enumerator: ...&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this application, though, I decided to immediately collect the results in an array with &lt;code&gt;to_a&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_a&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To calculate the primes, the English version was "going up a number list one by one, calling each element &lt;code&gt;x&lt;/code&gt; and crossing out all numbers from &lt;code&gt;x&lt;/code&gt; up to &lt;code&gt;n&lt;/code&gt; that are a multiple of &lt;code&gt;x&lt;/code&gt;."  Here's the Ruby:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="vi"&gt;@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="vi"&gt;@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;zero?&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll take that list we just made, &lt;code&gt;[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]&lt;/code&gt;, and successively call each one &lt;code&gt;x&lt;/code&gt;.  Then, we look at &lt;em&gt;every other&lt;/em&gt; element higher in the list, calling it &lt;code&gt;z&lt;/code&gt;, and delete any in that same list that satisfy &lt;code&gt;(z % x).zero?&lt;/code&gt;.  If the remainder when dividing &lt;code&gt;z&lt;/code&gt; by &lt;code&gt;x&lt;/code&gt; is zero, it's a multiple and therefore not a prime.  Deleting it from the list ensures we won't waste any more work on an eliminated member of the set.&lt;/p&gt;

&lt;p&gt;Before we even got to all this, though, there's a one-liner guard clause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="vi"&gt;@all&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;@all.empty?&lt;/code&gt; returns true, we know &lt;code&gt;@all == []&lt;/code&gt;, because arrays can respond to that message.  When that's the case, the empty list does indeed comprise all the primes up to &lt;code&gt;n&lt;/code&gt;, so pass it on up before moving further.  This is one particular case where I think this code should be improved - I know &lt;em&gt;in the constructor&lt;/em&gt; that the result will be the empty list.  However, I don't know how the requirements of this class might change (hypothetically), so I decided to not actually return that result until the &lt;code&gt;primes&lt;/code&gt; message is explicitly passed.  What's your instinct?&lt;/p&gt;

&lt;p&gt;However...that's it.  It's more or less what we said in English, but in Ruby.  When we eliminate all the numbers that are a multiple of one smaller, we get the primes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# after 2&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# after 3&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# None of the rest have any multiples in the set - these are the primes under 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All done.  You can almost read the code like the English:  "take each from @all as x, but specifically select the ones that are higher than x.  Delete it from @all if it's a perfect multiple of x".  And all along the way, each object already knew how to do or answer everything I needed.  All you have to do is ask.&lt;/p&gt;

&lt;p&gt;How would you write this simple program?&lt;/p&gt;

&lt;h2&gt;
  
  
  Aside
&lt;/h2&gt;

&lt;p&gt;On a more personal note, I've been pretty quiet this pandemic - haven't really known what to write while I shift gears and figure out the path forward, and it's been a bunch of rebuilding fundamentals in a more practical context.  There's been ample book-readin' (for tool-learnin' and ecosystem-familiarizin') and some problem solving on LeetCode-esque-sites (which have thoroughly humbled and redirected me), and some, you know, messing around and such (incoming &lt;a href="https://en.wikipedia.org/wiki/CHIP-8"&gt;chip8&lt;/a&gt; post, I got way bit-wiser).  And, like, a bunch of completely non-coding concerns - right?  Who's with me?  2020 can go suck it?&lt;/p&gt;

&lt;p&gt;Anyway, I've found it all challenging and necessary, but not necessarily post-inspiring.  However, I've definitely had my mind blown more than once, and these books are to blame:&lt;/p&gt;

&lt;p&gt;The Ruby-specific ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.poodr.com/"&gt;Practical Object-Oriented Design in Ruby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pragprog.com/titles/rails6/"&gt;Agile Web Development with Rails 6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pragprog.com/titles/ruby4/"&gt;Programming Ruby 1.9-2.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pragprog.com/titles/ppmetr2/"&gt;Metaprogramming Ruby 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's tough to recommend any over the other.  They're all quite different, and I'm finding each indispensable.&lt;/p&gt;

&lt;p&gt;The Random Other Crap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www-cs-faculty.stanford.edu/~knuth/taocp.html"&gt;The Art Of Computer Programming&lt;/a&gt; - hardly needs an introduction.  This is slow going, but not one page is a waste.  Put your Assembly cap on.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.sandervanvugt.com/red-hat-rhcsa-8-cert-guide-ex200/"&gt;RHCSA 8 Cert Guide&lt;/a&gt; - off topic, but also great if this is in your interests.  I also am watching this author's video course, and recommend his Linux instruction material.  Straight and to the point, does not waste your time.  I found I was already closer than I thought, this is perfect for filling in the gaps.  I'm taking &lt;a href="https://www.redhat.com/en/services/certification/rhcsa"&gt;the exam&lt;/a&gt; in a few weeks.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.pearson.com/us/higher-education/program/Goldstein-Calculus-Its-Applications-plus-My-Lab-Math-with-Pearson-e-Text-24-Month-Access-Card-Package-14th-Edition/PGM2548008.html"&gt;Calculus and its Applications&lt;/a&gt; - Also off-topic.  I'm taking Calc 1 in school for the first time, as a 28-year-old would-be engineer, and honestly, it's the most challenging material on here while also blowing my mind.  While there is additional course material, I have largely succeeded in the course by reading this textbook and attempting the homework, as someone who is not adept at math by nature.  Why didn't any of you tell me calculus was cool?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Cover image: &lt;span&gt;Photo by &lt;a href="https://unsplash.com/@mattseymour?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Matt Seymour&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/strainer?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
      <category>devjournal</category>
      <category>books</category>
    </item>
    <item>
      <title>Share Your Conway's Game Of Life</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Sun, 12 Apr 2020 17:02:37 +0000</pubDate>
      <link>https://forem.com/deciduously/share-your-conway-s-game-of-life-2b18</link>
      <guid>https://forem.com/deciduously/share-your-conway-s-game-of-life-2b18</guid>
      <description>&lt;p&gt;Sadly, &lt;a href="https://en.wikipedia.org/wiki/John_Horton_Conway"&gt;John Horton Conway&lt;/a&gt; has &lt;a href="https://www.i-programmer.info/news/82-heritage/13614-john-conway-dies-from-coronavirus.html"&gt;passed away&lt;/a&gt;.  While Conway's contributions to computational mathematics over the years are numerous and eclectic, many aspiring coders are introduced to his work via &lt;a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life"&gt;Conway's Game of Life&lt;/a&gt;, a cellular automaton that's relatively simple to implement.&lt;/p&gt;

&lt;p&gt;In the Game of Life, you provide an initial state, or seed, to a square grid of cells.  Each cell is either "on" or "off", and the next state of the grid is calculated via these rules, as stated on Wikipedia:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Any live cell with two or three live neighbors survives.&lt;/li&gt;
&lt;li&gt;Any dead cell with three live neighbors becomes a live cell.&lt;/li&gt;
&lt;li&gt;All other live cells die in the next generation. Similarly, all other dead cells stay dead.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As this is relatively simple to write logic for, many programmers take a stab at implementing such a program early in their careers.  Here's &lt;a href="https://github.com/deciduously/conway"&gt;mine on GitHub&lt;/a&gt;, from July 2017, as one of my first Rust programs - but not terribly interesting to look it as it just renders world states in text to the terminal.  However, it does demonstrate how trivial the core logic is to write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="c1"&gt;//tick_cell takes a Coord and a World and returns the next state of the cell&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;tick_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;World&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;moore_sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;get_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//ALIVE&lt;/span&gt;
            &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//overcrowded or starved&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//3 gives birth&lt;/span&gt;
            &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//barren&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you have a Game of Life to show us?  Bonus points for an implementation we can play with - my entry must be downloaded and compiled, but I'm sure some of you web-dev-y types have something more interactive!&lt;/p&gt;

&lt;p&gt;What are some of your favorite seeds?  Are there other cellular automata that interest you?&lt;/p&gt;

&lt;p&gt;Alternatively, what other John Conway work has inspired you?  According to &lt;a href="https://www.reddit.com/r/programming/comments/fzjg0q/rip_john_conway/fn4on9i?utm_source=share&amp;amp;utm_medium=web2x"&gt;this redditor&lt;/a&gt;, Conway was frustrated that the Game of Life was his most well-known contribution.  What else do you remember him for?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image: &lt;a href="https://en.wikipedia.org/wiki/File:Game_of_life_glider_gun.svg"&gt;wikimedia commons&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Quick And Dirty Java Makefile</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Wed, 08 Apr 2020 15:07:24 +0000</pubDate>
      <link>https://forem.com/deciduously/quick-and-dirty-java-makefile-4njo</link>
      <guid>https://forem.com/deciduously/quick-and-dirty-java-makefile-4njo</guid>
      <description>&lt;p&gt;I'm not a Java user and know next to nothing about it.  Today was my first time ever running a line of Java directly.  If you've &lt;em&gt;ever&lt;/em&gt; used Java before, this is not going to blow your mind.&lt;/p&gt;

&lt;p&gt;As part of my Ruby learning journey I'm working on translating some Java (specifically from the excellent &lt;a href="https://craftinginterpreters.com/"&gt;Crafting Interpeters&lt;/a&gt; book), and while my Ruby implementation is the focus I want to be able to follow along locally with both languages.  However, I didn't want to spend a ton of time learning about a whole ecosystem that I'm not targeting.  Previously, I'd always assumed Java required bulky build tools and IDEs and lots of peripheral knowledge to hook everything up.  I thought I &lt;em&gt;needed&lt;/em&gt; use a full-fledged tool like Eclipse or IDEA to set up all the details for you and had no sense of how the build process worked.&lt;/p&gt;

&lt;p&gt;As it turns out, while you can lean on tooling, you can of course &lt;em&gt;also&lt;/em&gt; just pop some Java code in a text file and build and run it by hand!  There is a &lt;code&gt;javac&lt;/code&gt; CLI tool.  Either use it directly or use GNU make to invoke it automatically.&lt;/p&gt;

&lt;p&gt;Here's what I'm starting with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;JAVAC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;javac
&lt;span class="nv"&gt;sources&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wildcard&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.java&lt;span class="nf"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$(sources:.java=.class)&lt;/span&gt;

&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;program&lt;/span&gt;

&lt;span class="nl"&gt;program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(classes)&lt;/span&gt;

&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.class

&lt;span class="nl"&gt;%.class&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;%.java&lt;/span&gt;
    &lt;span class="nv"&gt;$(JAVAC)&lt;/span&gt; &lt;span class="nv"&gt;$&amp;lt;&lt;/span&gt;

&lt;span class="nl"&gt;jar&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(classes)&lt;/span&gt;
    jar cvf program.jar &lt;span class="nv"&gt;$(classes)&lt;/span&gt;

&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;all program clean jar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;edit: added phony targets!  Thanks Michael.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With this, you can invoke &lt;code&gt;make&lt;/code&gt; to compile a &lt;code&gt;Thing.class&lt;/code&gt; bytecode file for each &lt;code&gt;Thing.java&lt;/code&gt; source file present.  Then you get to run &lt;code&gt;java Thing&lt;/code&gt; to execute it!  You can also use &lt;code&gt;make jar&lt;/code&gt; to roll everything together into a jar file.&lt;/p&gt;

&lt;p&gt;All in all, not so different from anything else I've ever used!&lt;/p&gt;

&lt;p&gt;This is, as promised, "quick and dirty".  You can go forth from here and further customize your makefile, but if you want to do more than just quick experimentation, I do still think the IDE/Java-specific build tool route (&lt;a href="https://maven.apache.org/"&gt;Maven&lt;/a&gt;, &lt;a href="https://gradle.org/"&gt;Gradle&lt;/a&gt;, etc) is gonna be the way to go.  For non-Java-users who just want to plunk about without wasting too much time on peripherals, though, this'll do you just fine.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by Jakub Dziubak on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>makefile</category>
      <category>beginners</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Setting Up A Fresh Ruby Project</title>
      <dc:creator>Ben Lovy</dc:creator>
      <pubDate>Thu, 19 Mar 2020 13:05:20 +0000</pubDate>
      <link>https://forem.com/deciduously/setting-up-a-fresh-ruby-project-56o4</link>
      <guid>https://forem.com/deciduously/setting-up-a-fresh-ruby-project-56o4</guid>
      <description>&lt;p&gt;To start up a Ruby project, you don't need to do anything other than put some Ruby code in a file and invoke it with &lt;code&gt;ruby program.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As projects grow, though, you'll likely add dependencies and tests.  You can mitigate this with documentation - tell users what gems they need to pull, and which files contain the test suites - but that becomes unwieldy quick.  It's much better to lean on ecosystem tools to specify and automate your build steps.&lt;/p&gt;

&lt;p&gt;To follow along, you'll need &lt;a href="https://www.ruby-lang.org/en/" rel="noopener noreferrer"&gt;Ruby&lt;/a&gt; installed.  The latest at time of writing is version 2.7.0.&lt;/p&gt;

&lt;p&gt;EDIT: If you don't want to do this from scratch, try &lt;code&gt;bundler gem&lt;/code&gt;:&lt;/p&gt;


&lt;div class="liquid-comment"&gt;
    &lt;div class="body"&gt;
      &lt;p&gt;Comment Not Found&lt;/p&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Make a directory
&lt;/h2&gt;

&lt;p&gt;Don't just spread your ruby source all across your home directory - keep your projects self contained.  Create a directory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ mkdir ruby_project


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open this directory in your favorite editor.  Everything else in this post goes in here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Bundler
&lt;/h2&gt;

&lt;p&gt;To manage dependencies, use &lt;a href="https://bundler.io/" rel="noopener noreferrer"&gt;Bundler&lt;/a&gt;.  This tool allows you to specify gems required to run your project and lets users issue a single &lt;code&gt;bundle install&lt;/code&gt; command to pull down any required.&lt;/p&gt;

&lt;p&gt;First, install the gem in you haven't already:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;

&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;bundler&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then, create a file called &lt;code&gt;Gemfile&lt;/code&gt; in your project root.  For now, we'll just specify the package repository URL:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;

&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="s1"&gt;'https://rubygems.org'&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As we need dependencies, we'll add them here below this line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a Test file
&lt;/h2&gt;

&lt;p&gt;The first dependency we need is for testing.  This example uses &lt;a href="https://github.com/seattlerb/minitest" rel="noopener noreferrer"&gt;minitest&lt;/a&gt;.  Add that to your &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;  source 'https://rubygems.org'
&lt;span class="gi"&gt;+ gem 'minitest'
&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now you can invoke &lt;code&gt;bundle install&lt;/code&gt; to pull this down automatically.  When you do, a new file called &lt;code&gt;Gemfile.lock&lt;/code&gt; will be generated containing the specific package version in use.&lt;/p&gt;

&lt;p&gt;This is really up to you, but I like keeping my tests in a separate subdirectory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ mkdir test


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Create a file in this folder called &lt;code&gt;test/cool_program_test.rb&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# frozen_string_literal: true&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'minitest/autorun'&lt;/span&gt;
&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'../lib/cool_program'&lt;/span&gt;

&lt;span class="c1"&gt;# Test program coolness&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoolProgramTest&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Minitest&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Test&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_coolness_off_the_charts&lt;/span&gt;
    &lt;span class="c1"&gt;# skip&lt;/span&gt;
    &lt;span class="n"&gt;assert_equal&lt;/span&gt; &lt;span class="no"&gt;CoolProgram&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;coolness&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The first line, &lt;code&gt;# frozen_string_literal: true&lt;/code&gt;, is a magic comment that is kind of like calling &lt;code&gt;Object.freeze&lt;/code&gt; on every string literal.  This is done for performance reasons, but you can opt out for a given string by prefixing it with a &lt;code&gt;+&lt;/code&gt; character: &lt;code&gt;+'my newly mutable string literal'&lt;/code&gt;.  Now you can do &lt;code&gt;my_str &amp;lt;&amp;lt; some_other_str&lt;/code&gt;.  In Ruby, though, I'm not finding myself manipulating strings like this.&lt;/p&gt;

&lt;p&gt;We know we'll be able to use the &lt;code&gt;minitest&lt;/code&gt; dependency in the first line because we specified it with Bundler.  The actual source code doesn't exist yet, though!&lt;/p&gt;

&lt;h2&gt;
  
  
  Add an Implementation File
&lt;/h2&gt;

&lt;p&gt;This is also personal preference, but it's a sensible idea to keep your implementations in a separate subdirectory as well:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ mkdir lib


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Create the file we pulled into the test file at &lt;code&gt;lib/cool_program.rb&lt;/code&gt; with these contents:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# frozen_string_literal: true&lt;/span&gt;

&lt;span class="c1"&gt;# The coolest program&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoolProgram&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:coolness&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@coolness&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Coolness: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CoolProgram&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;coolness&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/10"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Groovy!  Everything's in place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a Rakefile
&lt;/h2&gt;

&lt;p&gt;Now, we could just direct users to invoke &lt;code&gt;ruby&lt;/code&gt; themselves on the proper files - &lt;code&gt;ruby lib/cool_program.rb&lt;/code&gt; to run the program, or &lt;code&gt;ruby test/cool_program_test.rb&lt;/code&gt; for the tests.  It would be better if we could specify those paths and abstract into &lt;code&gt;test&lt;/code&gt; or &lt;code&gt;run&lt;/code&gt; operations.  That's what &lt;a href="https://github.com/ruby/rake" rel="noopener noreferrer"&gt;&lt;code&gt;rake&lt;/code&gt;&lt;/a&gt; is for!  This tool is a lot like GNU Make, but for Ruby.&lt;/p&gt;

&lt;p&gt;First, add it to your &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;  source 'https://rubygems.org'
  gem 'minitest'
&lt;span class="gi"&gt;+ gem 'rake'
&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then, add a new file in your project root called &lt;code&gt;Rakefile&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;

&lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="sx"&gt;%w[test]&lt;/span&gt;

&lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ss"&gt;:run&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;ruby&lt;/span&gt; &lt;span class="s1"&gt;'lib/cool_program.rb'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;ruby&lt;/span&gt; &lt;span class="s1"&gt;'test/cool_program_test.rb'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you know how &lt;code&gt;make&lt;/code&gt; works, this is similar (if you don't, I've &lt;a href="https://dev.to/deciduously/how-to-make-a-makefile-1dep"&gt;got ya covered&lt;/a&gt;).  The first line defines the default task, or what happens when you invoke &lt;code&gt;rake&lt;/code&gt; without specifying a specific task.  In this case, we just have it run the &lt;code&gt;test&lt;/code&gt; task as a dependency with no block itself.  This is a list, you can specify multiple tasks here.&lt;/p&gt;

&lt;p&gt;Each task below can be invoked at the command line directly - you'd use &lt;code&gt;rake run&lt;/code&gt; to actually execute your program and just &lt;code&gt;rake&lt;/code&gt; on its own to run the test suite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a Linter
&lt;/h2&gt;

&lt;p&gt;I've become fairly reliant on the &lt;a href="https://github.com/rubocop-hq/rubocop" rel="noopener noreferrer"&gt;Rubocop&lt;/a&gt; linter to keep me in line with the &lt;a href="https://rubystyle.guide/" rel="noopener noreferrer"&gt;Ruby style guide&lt;/a&gt;.  It now ships with a ready-to-go Rake task.&lt;/p&gt;

&lt;p&gt;First, add it to your &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;  source 'https://rubygems.org'
  gem 'minitest'
  gem 'rake'
&lt;span class="gi"&gt;+ gem 'rubocop'
&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then, modify your &lt;code&gt;Rakefile&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gi"&gt;+ require 'rubocop/rake_task'
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;- task default: %w[test]
&lt;/span&gt;&lt;span class="gi"&gt;+ task default: %w[lint test]
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+ RuboCop::RakeTask.new(:lint) do |task|
+   task.patterns = ['lib/**/*.rb', 'test/**/*.rb']
+   task.fail_on_error = false
+ end
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  task :run do
    ruby 'lib/cool_program.rb'
  end
&lt;span class="err"&gt;
&lt;/span&gt;  task :test do
    ruby 'test/cool_program_test.rb'
  end
&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It's my personal preference to run the linter and the tester by default, but not fail on lint errors.  &lt;a href="https://docs.rubocop.org/en/stable/integration_with_other_tools/#rake-integration" rel="noopener noreferrer"&gt;Season to taste&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional - Add a GitHub Action
&lt;/h2&gt;

&lt;p&gt;I host almost all my code on GitHub and have become a fan of GitHub Actions.  Using YAML, you can have GitHub automatically run your tests whenever you commit or open a PR.  Create a new file at &lt;code&gt;&amp;lt;project root&amp;gt;/.github/workflows/ruby.yml&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ruby&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Ruby &lt;/span&gt;&lt;span class="m"&gt;2.7&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-ruby@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;ruby-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2.7.x&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and test with Rake&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;gem install bundler&lt;/span&gt;
        &lt;span class="s"&gt;bundle install --jobs 4 --retry 3&lt;/span&gt;
        &lt;span class="s"&gt;bundle exec rake&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can tweak each step very easily here - the commands specified will get run and if everything completes without errors, you get a green check mark.  Sweet!  Using &lt;code&gt;rake&lt;/code&gt; allows this file to stay concise, and then you'd be able to manage changes to your structure in your Rakefile without having to worry about this file at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a README and stuff
&lt;/h2&gt;

&lt;p&gt;We're just about done, but you should always include a README:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;

&lt;span class="gh"&gt;# ruby_project&lt;/span&gt;

The coolest dang program that you ever did see.

&lt;span class="gu"&gt;## Dependencies&lt;/span&gt;
&lt;span class="p"&gt;
*&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Ruby&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://www.ruby-lang.org/en/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;.  Written with version &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;2.7.0&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://www.ruby-lang.org/en/news/2019/12/25/ruby-2-7-0-released/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; - &lt;span class="ge"&gt;*[docs](https://docs.ruby-lang.org/en/2.7.0/)*&lt;/span&gt;.

&lt;span class="gu"&gt;## Usage&lt;/span&gt;

Install deps: &lt;span class="sb"&gt;`gem install bundler &amp;amp;&amp;amp; bundle install`&lt;/span&gt;.  Run &lt;span class="sb"&gt;`bundle exec rake`&lt;/span&gt; to run the tests, or &lt;span class="sb"&gt;`bundle exec rake run`&lt;/span&gt; to run the program.&lt;span class="sb"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add a &lt;code&gt;.gitignore&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

*.gem
*.rbc
/.config
/coverage/
/InstalledFiles
/pkg/
/spec/reports/
/spec/examples.txt
/test/tmp/
/test/version_tmp/
/tmp/

## Environment normalization
/.bundle/
/vendor/bundle
/lib/bundler/man/

# Used by RuboCop. Remote config files pulled in from inherit_from directive.
.rubocop-https?--*


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You should probably add a LICENSE file, too - here's the &lt;a href="https://opensource.org/licenses/BSD-3-Clause" rel="noopener noreferrer"&gt;BSD-3-Clause&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Copyright 2020 Coolness McAwesome

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;At the end, your directory should look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ tree
.
|____Gemfile.lock
|____.gitignore
|____.github
| |____workflows
| | |____ruby.yml
|____Gemfile
|____LICENSE
|____Rakefile
|____test
| |____cool_program_test.rb
|____README.md
|____lib
| |____cool_program.rb


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, &lt;code&gt;git init &amp;amp;&amp;amp; git add . &amp;amp;&amp;amp; git commit -m "Initial commit"&lt;/code&gt;.  Happy hacking!&lt;/p&gt;

&lt;p&gt;If you don't feel a pressing need to do this from scratch, you can just use &lt;a href="https://github.com/deciduously/ruby-template" rel="noopener noreferrer"&gt;this GitHub template&lt;/a&gt; with the code from this post.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by Jukan Tateisi on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
