おはこんばんにちは、 pojiro です。
今回は Nerves は関係なく、Rust をさわったことのない私が Rustler を 雰囲気で書き始める記事になります。
環境
変な時間に目が覚めて書いており、手元の環境がいつもと違って Windows です。このまま進めていきます。
- WSL には Ubuntu 20.04 が入っています。
- Elixir & Erlang は asdf でインストール済みです。
- Rust は https://www.rust-lang.org/ja/tools/install の WSL 向けの方法でインストール済みです。
導入
Elixir のプロジェクトを作って、
mix new learn_rustler
...
cd learn_rustler
何はなくとも Git 管理の準備をして、
git init .
git config user.name "Your name"
git config user.email your@email.address
git add .
git commit -m "Initial commit"
Rustler のドキュメントに従って、mix.exs を 開いて deps に rustler を追加して、
defp deps do
[
{:rustler, "~> 0.30.0", runtime: false}
]
end
Fetch all necessary dependencies
mix deps.get
Check your installation by showing help from the installed Mix task
mix help rustler.new
** (Mix) The task "rustler.new" could not be found
あれ?となりますが、これはコンパイルしてないからなので、
mix compile
mix help rustler.new
mix rustler.new
Generates boilerplate for a new Rustler project.
Usage:
mix rustler.new [--module <Module>] [--name <Name>] [--otp-app <OTP App>]
Location: _build/dev/lib/rustler/ebin
あっさりしてます。が、インストールできていることのチェックらしいので、こんなものなんでしょう。
Generate the boilerplate for a new Rustler project. Follow the instructions to configure your project:
mix rustler.new # 実行すると対話式になりました。
This is the name of the Elixir module the NIF module will be registered to.
Module name > LearnRustler.Nif # 入力
This is the name used for the generated Rust crate. The default is most likely fine.
Library name (learnrustler_nif) > learn_rustler_nif # default は _ が入ってないのが嫌なので修正
* creating native/learn_rustler_nif/.cargo/config.toml
* creating native/learn_rustler_nif/README.md
* creating native/learn_rustler_nif/Cargo.toml
* creating native/learn_rustler_nif/src/lib.rs
* creating native/learn_rustler_nif/.gitignore
Ready to go! See /home/pojiro/Repos/learn_rustler/native/learn_rustler_nif/README.md for further instructions.
出力の最終行に
See /home/pojiro/Repos/learn_rustler/native/learn_rustler_nif/README.md for further instructions.
とあるので、見ると
## To load the NIF:
```elixir
defmodule LearnRustler.Nif do
use Rustler, otp_app: :learn_rustler, crate: "learn_rustler_nif"
# When your NIF is loaded, it will override this function.
def add(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
end
\```
このモジュールを追加すればよさそうです。
mkdir lib/learn_rustler
vim lib/learn_rustler/nif.ex
# コードの貼り付け
実行できるかな? iex -S mix
でシェルを立ち上げると
Compiling 1 file (.ex)
Updating crates.io index
Downloaded unreachable v1.0.0
Downloaded heck v0.4.1
Downloaded memchr v2.6.4
Downloaded unicode-ident v1.0.12
Downloaded quote v1.0.33
Downloaded proc-macro2 v1.0.70
Downloaded syn v2.0.41
Downloaded regex-syntax v0.8.2
Downloaded regex-automata v0.4.3
Downloaded regex v1.10.2
Downloaded void v1.0.2
Downloaded lazy_static v1.4.0
Downloaded aho-corasick v1.1.2
Downloaded rustler_sys v2.3.1
Downloaded rustler v0.30.0
Downloaded rustler_codegen v0.30.0
Downloaded 16 crates (2.0 MB) in 1.27s
Compiling crate learn_rustler_nif in release mode (native/learn_rustler_nif)
Compiling memchr v2.6.4
Compiling regex-syntax v0.8.2
Compiling proc-macro2 v1.0.70
Compiling unicode-ident v1.0.12
Compiling void v1.0.2
Compiling heck v0.4.1
Compiling lazy_static v1.4.0
Compiling unreachable v1.0.0
Compiling aho-corasick v1.1.2
Compiling quote v1.0.33
Compiling syn v2.0.41
Compiling regex-automata v0.4.3
Compiling regex v1.10.2
Compiling rustler_sys v2.3.1
Compiling lib/learn_rustler/nif.ex (it's taking more than 10s)
Compiling rustler_codegen v0.30.0
Compiling rustler v0.30.0
Compiling learn_rustler_nif v0.1.0 (/home/pojiro/Repos/learn_rustler/native/learn_rustler_nif)
Finished release [optimized] target(s) in 9.27s
おお、ビルドが走りました。ということは、
iex(1)> LearnRustler.Nif.add(1, 2)
3
ばっちり、動きました!
ここまではすんなりこれましたが、Rustler から Tuple をどう返すか? Elixir から List や Tuple をどう渡すのかを知らないと使えるコードが書けないです。
これ以降は随時追記していけたらとおもいます。今日(12/17)はいったんここまで。
基礎
続くはず!
いろいろ調べたのですが、 Rustler のテストコードが一番、使い方が分かって良い気がしました。
つまり、👇を見るべし!
このテストを見ながら実装したのが Zenohex v0.2.0 👇です!