Skip to content

Instantly share code, notes, and snippets.

@havenwood
Last active March 24, 2026 17:35
Show Gist options
  • Select an option

  • Save havenwood/ae747a713c59fb3849b53db57ee088dd to your computer and use it in GitHub Desktop.

Select an option

Save havenwood/ae747a713c59fb3849b53db57ee088dd to your computer and use it in GitHub Desktop.
FizzBrrr
defmodule FizzBuzz.Native do
@moduledoc false
use Rustler, otp_app: :fizz_buzz
def classify(_nums), do: :erlang.nif_error(:nif_not_loaded)
end
defmodule FizzBuzz do
@moduledoc "FizzBuzz classification backed by a Rust NIF."
@typedoc "A divisibility label or the number itself."
@type classification() :: :fizz | :buzz | :fizz_buzz | integer()
@doc """
Classifies numbers by divisibility.
## Examples
iex> FizzBuzz.classify([1, 3, 5, 15])
[1, :fizz, :buzz, :fizz_buzz]
"""
@spec classify([integer()]) :: [classification()]
defdelegate classify(nums), to: FizzBuzz.Native
end
//! NIFs for `FizzBuzz` classification.
use rustler::NifUnitEnum;
use rustler::NifUntaggedEnum;
/// A divisibility label.
#[derive(NifUnitEnum)]
enum Label {
Fizz,
Buzz,
FizzBuzz,
}
/// Either a divisibility label or the number itself.
#[derive(NifUntaggedEnum)]
enum Classification {
Divisible(Label),
Indivisible(i64),
}
/// Classifies a number based on divisibility by 3 and 5.
impl From<i64> for Classification {
fn from(num: i64) -> Self {
match (num % 3, num % 5) {
(0, 0) => Self::Divisible(Label::FizzBuzz),
(0, _) => Self::Divisible(Label::Fizz),
(_, 0) => Self::Divisible(Label::Buzz),
_ => Self::Indivisible(num),
}
}
}
/// Exposes `FizzBuzz.classify/1` as a NIF.
///
/// Returns a list of integers, `:fizz`, `:buzz` and `:fizz_buzz` on the Elixir side.
///
/// Pulls ahead of pure Elixir around a thousand elements by amortizing the NIF
/// boundary cost. Runs on a dirty CPU scheduler so long lists won't block BEAM
/// schedulers.
#[rustler::nif(schedule = "DirtyCpu")]
fn classify(nums: Vec<i64>) -> Vec<Classification> {
nums.into_iter().map(Classification::from).collect()
}
rustler::init!("Elixir.FizzBuzz.Native");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment