-
Notifications
You must be signed in to change notification settings - Fork 228
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
52 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Upgrade | ||
|
||
This document here is intended to simplify upgrading to newer versions by extending the changelog. | ||
|
||
## 0.21 -> 0.22 | ||
|
||
0.22 changes how to define NIFs. Users upgrading to 0.22 should to do two things: | ||
|
||
1. Replace `rustler::rustler_export_nifs!` with `rustler::init!` | ||
2. Use the new `rustler::nif` proc_macro to declare NIFs | ||
|
||
0.22 introduces a new `proc_macro` allowing to spell out the parameter of a NIF | ||
directly instead of using an `args: &[Term<'a>]`. Lets consider an example `add()`, | ||
where the Elixir function looks like this: | ||
|
||
```elixir | ||
def add(left, right), do: :erlang.nif_error(:not_loaded) | ||
``` | ||
|
||
Previously, the signature of the corresponding NIF might have looked like this: | ||
|
||
```rust | ||
fn add<'a>(env: Env<'a>, args: &[Term<'a>]) -> Result<Term<'a>, Error> | ||
``` | ||
|
||
When calling the NIF from Elixir as `add(1, 2)`, `args` would then contain two | ||
`Term`, one for 1, and one for 2. With 0.22, this becomes more obvious, as the | ||
NIFs signature resembles the Elixir function's signature: | ||
|
||
```rust | ||
#[rustler::nif] | ||
fn add(a: i64, b: i64) -> i64 | ||
``` | ||
|
||
Under the hood, this is implemented by the `rustler::nif` proc_macro. For the | ||
new form to work, the parameters' types need to implement `Decoder`, and the | ||
return type needs to implement `Decoder`. | ||
### What if `Env` is required in the function? | ||
Sometimes, we still need the environment `Env` for the NIF. For example, if | ||
work with `Binary` and `OwnedBinary`, the environment would be needed to create a `Binary` | ||
from an `OwnedBinary`. To allow this, `env: Env<'a>` can be added explicitly as well: | ||
|
||
```rust | ||
#[rustler::nif] | ||
pub fn map_entries_sorted<'a>(env: Env<'a>, iter: MapIterator<'a>) -> NifResult<Vec<Term<'a>>> | ||
``` | ||
|
||
`env` can then be used the same way as before. |