Skip to content

brucify/rebar3_rustler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rebar3 rustler plugin

Hex.pm package version Last Updated

A basic set of rebar3 templates to aid creating rustler-based Erlang NIFs (Native Implemented Functions), allowing us to call Rust from Erlang. This plugin uses rebar3_cargo to compile Rust crates in the crates directory and copy all binary outputs to priv/crates/<cratename>/<binary>.

2 templates are provided:

  • rustler_lib for generating a complete Rustler-based Erlang NIF library
  • rustler_nif for generating new Rustler-based NIF in an existing Erlang app

Structure of the generated NIF library. An example can be found here.

├── rebar.config
└── src
    ├── my_nif.app.src
    └── my_nif.erl
├── priv
├── native
│   └── my_nif
│       ├── Cargo.toml
│       └── src
│           └── lib.rs

Usage

Use the plugin by adding the following to ~/.config/rebar3/rebar.config

{plugins, [rebar3_rustler]}.

Running rebar3 new should now show extra templates available:

$ rebar3 new
...
rustler_lib (plugin): Complete Erlang NIF library written in Rust using rustler
rustler_nif (plugin): A basic Erlang NIF written in Rust using rustler
...

Creating a new Erlang NIF library

$ rebar3 new rustler_lib my_nif # change my_nif to whatever you want to call your lib
$ cd my_nif
$ make

Compiling the app will fetch dependencies for both Erlang and Rust:

===> Fetching rebar3_cargo v0.1.0
===> Fetching cargo v0.1.2
===> Fetching jsx v2.11.0
...
    Compiling regex v1.7.0
    Compiling rustler_sys v2.2.0
    Compiling rustler_codegen v0.26.0
    Compiling my_nif v0.1.0 (/Users/bruce/git/my_nif/native/my_nif)
    Finished dev [unoptimized + debuginfo] target(s) in 6.08s
===>   Copying libmy_nif...
===> Analyzing applications...
===> Compiling my_nif

To check if we can call Rust from the Erlang shell:

1> my_nif:add(2, 2).
4

Creating a NIF in an existing Erlang app

$ cd my_app                      # change my_app to your existing app name               
$ rebar3 new rustler_nif my_nif

Then follow the instructions in native/my_nif/README.md

Testing

Running Erlang eunit tests will also invoke cargo test in the Rust crate, thanks to the rebar3_cargo plugin.

$ rebar3 eunit    # unit tests

Options

Pass options as usual to the rebar3_cargo plugin.

{cargo_opts, [
    {src_dir, "native/my_nif"}
]}.

{provider_hooks, [
    {pre, [
        {compile, {cargo, build}}
    ]},
    {post, [
        {clean, {cargo, clean}},
        {eunit, {cargo, test}}
    ]}
]}.

License

Copyright 2022 Bruce Yinhe

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Acknowledgment

This plugin is based on rebar3_cargo