It’s occasionally useful to introduce pause points into procedures. The idea is that, when a human operator is about to do something scary, we want them to stop and think for a second and not just do things by rote. Enter challenge-prompt, a small program and Rust library which challenges the user to type something.

You can install it from crates.io:

$ cargo install challenge-prompt

Without any arguments, the program issues an arithmetic challenge:

$ challenge-prompt
Solve: (5 + 15) mod 5 = ?

It can also make the user type in a phrase exactly:

$ challenge-prompt -p "I am probably making a mistake"
Enter the following exactly to continue: I am probably making a mistake

It can also output a vanilla yes/no prompt, but my experience is that it’s very easy to internalise typing ‘y’ after commands:

$ challenge-prompt -y
Continue? [y]

All of this is also exposed as a Rust library.

An aside on Rust binary sizes

Updated on 2022-04-30 for Rust 1.60.

If you’re looking for a way to make Rust binaries smaller, see also min-sized-rust.

One issue I had writing challenge-prompt is that Rust binaries tend to be big. This is generally not a problem, but there’s something aesthetically displeasing about a program as simple as challenge-prompt being multiple megabytes in size.

Back in 2018, a release build of challenge-prompt was 4 MB with the default settings. As of 2022, that’s gone down to 0.5 MB. So, the suggestions in this section lead to less striking reductions in size.

I found that the following settings struck a good balance between size and additional complexity. They are ordered in decreasing order of size improvement.

  1. Put any dev-only dependencies in [dev-dependencies] so that they don’t get included in the release build.

  2. Enable Link Time Optimisations for the release profile in Cargo.toml:

    [profile.release]
    lto = true
    
  3. Abort on panic in Cargo.toml:

    [profile.release]
    panic = "abort"
    
  4. Strip symbols:

    [profile.release]
    strip = "symbols"
    
  5. Set the optimisation level to “size”:

    [profile.release]
    opt-level = "z"
    

These all reduced challenge-prompt’s size from 500 KB to around 300 KB.

Dropping the dependency on stdlib would have likely further reduce the size, but that would make the code too fiddly for my tastes.