Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Rustler

livebooks/rustler/rustler.livemd

Rustler

Mix.install([
  {:rustler, "~> 0.35.1"}
])

Generate Rust project

File.cd("/tmp")
module = "LearnRustler.Nif"
name = "learn_rustler_nif"
Mix.Tasks.Rustler.New.run(["--module", module, "--name", name])
native_path = Path.join([File.cwd!(), "native", name])
src_path = Path.join([native_path, "src", "lib.rs"])
File.write!(src_path, """
#[rustler::nif]
fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[rustler::nif]
fn multiply(a: i32, b: i32) -> i32 {
    a * b
}

#[rustler::nif]
fn sort(v: Vec) -> Vec {
    let mut sorted = v;
    sorted.sort();
    sorted
}

#[rustler::nif]
fn hello(name: &str) -> String {
    format!("Hello, {}", name)
}

rustler::init!("Elixir.LearnRustler.Nif");
""")

Build Rust project

System.cmd(
  "cargo",
  ["rustc", "--release"],
  cd: native_path,
  stderr_to_stdout: true,
  into: IO.stream(:stdio, :line)
)
lib_path = Path.join([native_path, "target", "release", "liblearn_rustler_nif"])

Load NIF

defmodule LearnRustler.Nif do
  def load(path), do: :erlang.load_nif(path, 0)

  def add(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
  def multiply(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
  def sort(_v), do: :erlang.nif_error(:nif_not_loaded)
  def hello(_name), do: :erlang.nif_error(:nif_not_loaded)
end
LearnRustler.Nif.load(lib_path)
LearnRustler.Nif.add(3, 4)
LearnRustler.Nif.multiply(3, 4)
LearnRustler.Nif.sort([8, 5, 6, 2])
LearnRustler.Nif.hello("Rust")