Intro to Rust Macros


First Macro: timeit!

Jul - 2020 (~7 minutes read time)

This series serves as a practical (but not-exhaustive) introduction to declarative macro_rules!. I've put together some Rust macro examples to show how macros can be helpful for improving ergonomics around repetitive or error-prone tasks. The examples cover some great scenarios for macros like:

  • Print out the time a block of code takes to execute
  • Adding retries around intermittently fallible code
  • Making data structure initialization easier for common options

retry! Macro with Repetitive Matching and Nesting

Jul - 2020 (~8 minutes read time)

We previously covered a very basic declarative macro that wrapped some timing logic around a function to be run. This article expands on that with some additional matching techinques to build a retry! macro to be used like:

let res = retry!(|| { sometimes_fail(10) });
assert!(res.is_ok());

let res = retry!(sometimes_fail, 10; retries = 3);
assert!(res.is_ok());

Improved Retryable Logic with Macro Setup

Aug - 2020 (~3 minutes read time)

We've now built a simple retry! macro where the limited logic is contained in the macro_rules. This article will focus on an improved Retryable struct (with RetryStrategy) that we'll then build a new macro to simplify instantation for.

Retryable & RetryStrategy

Forgoing macros for a bit, let's setup some retry structs and implementations. First is a Retryable struct to contain our function/closure to retry, and a RetryStrategy with options for retrying (number of retries, delay, etc.):