Menulis NIF Rust dengan Rustler
Kali ini saya ingin berbagi pengetahuan mengenai cara menulis NIF dengan Rustler
tapi sebelum itu saya ingin mengenalkan apa itu NIF
. NIF kependekan dari Native Implemented Function yaitu memanggil fungsi dari pustaka luar. Kenapa harus menggunakan NIF? alasan pertama karena beberapa fungsi pada pustaka tertentu tidak ada di elixir, alasan kedua yaitu agar performa aplikasi meningkat. NIF biasanya dibuat dengan bahasa C namun kali ini saya ingin menggunakan bahasa Rust karena alasan keamanan dan kecepatan. Pustaka rustler mengklaim library yang ditulis tidak akan menyebabkan virtual mesin BEAM crash sehingga kita tidak perlu khawatir dan fokus ke penulisan pustaka.
Ok kita mulai saja, pertama buat project elixir dengan command mix. Pertama-tama buat project elixir dengan nama hello_nif
$ mix new hello_nif

Lalu tambahkan pustaka rustler ke file mix.exs
defp deps do
[
{:rustler, "~> 0.21.0"}
]
end
Kemudian jalankan mix deps.get
$ mix deps.get

Setelah itu compile project elixir dengan mix compile agar mix task dari rustler muncul
$ mix compile

Kemudian kita akan memulai membuat pustaka nif. Untuk nama modul kita samakan dengan nama project elixir yaitu HelloNif dan nama libnya hello_nif. rustler akan membuatkan rust project yang akan mengkompile otomatis saat kita menjalankan mix compile
atau iex -S mix
$ mix rustler.new
This is the name of the Elixir module the NIF module will be registered to.
Module name > HelloNif
This is the name used for the generated Rust crate. The default is most likely fine.
Library name (hellonif) > hello_nif
* creating native/hello_nif/.cargo/config
* creating native/hello_nif/README.md
* creating native/hello_nif/Cargo.toml
* creating native/hello_nif/src/lib.rs
Ready to go! See /home/susilo/var/Elixir/hello_nif/native/hello_nif/README.md for further instructions.
Maka akan ada folder native/hello_nif didalam folder project elixir, folder ini akan berisi pustaka nif yang kita buat dengan perintah mix rustler.new
. source code dari lib.rs kurang lebih akan seperti dibawah ini
#[macro_use] extern crate rustler;
use rustler::{Encoder, Env, Error, Term};
mod atoms {
rustler_atoms! {
atom ok;
//atom error;
//atom __true__ = "true";
//atom __false__ = "false";
}
}
rustler::rustler_export_nifs! {
"Elixir.HelloNif",
[
("add", 2, add)
],
None
}
fn add<'a>(env: Env<'a>, args: &[Term<'a>]) -> Result<Term<'a>, Error> {
let num1: i64 = args[0].decode()?;
let num2: i64 = args[1].decode()?;
Ok((atoms::ok(), num1 + num2).encode(env))
}
Kode diatas hanya ada satu fungsi yaitu add
dengan 2 parameter berupa angka. rustler_atoms!
berguna untuk membuat atom elixir dan rustler::rustler_export_nifs!
berguna untuk mengexport modul dan fungsinya sehingga dapat diakses dari elixir.
Langkah selanjutnya adalah menambah informasi agar mix dapat mengkompile pustaka yang kita buat. tambahkan custom compiler dan daftar pustaka nif ke dalam fungsi project, lalu buat fungsi rustler_crates yang memuat lokasi pustaka nif.
defmodule HelloNif.MixProject do
use Mix.Project
def project do
[
...
compilers: [:rustler] ++ Mix.compilers(),
rustler_crates: rustler_crates(),
...
]
end
defp rustler_crates do
[
hello_nif: [path: "native/hello_nif", mode: if(Mix.env() == :prod, do: :release, else: :debug)],
]
end
end
Langkah selanjutnya adalah menambahkan use Rustler
dan definisi nama fungsi pada modul HelloNif
sehingga fungsi yang dibuat dengan rust dapat diakses di dalam elixir.
defmodule HelloNif do
use Rustler, otp_app: :hello_nif, crate: :hello_nif
def add(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
def hello do
:world
end
end
Kemudian kita bisa mengujinya menggunakan interaktif elixir atau iex
dengan cara mengetikan perintah berikut ini pada terminal
$ iex -S mix
Pada saat kita menjalankan perintah iex -S mix
library dari rustler akan otomatis mengkompile pustaka yang kita tulis dengan bahasa pemrograman rust.
Setelah rustler selesai mengkompile pustaka maka konsol iex
juga akan muncul. nah setelah muncul kita bisa mencoba mengakses fungsi yang telah kita buat dengan rust.
iex(1)> HelloNif.add(1, 2)
{:ok, 3}
iex(2)>
Jika tidak ada error maka akan keluar pesan berupa tuple atom :ok
dan angka 3.
Sekian semoga bermanfaat.