rustler

repository·master·Indexed 26 days ago

https://github.com/rusterlium/rustler

A library for writing safe Erlang NIFs (Native Implemented Functions) in Rust. It provides tools to prevent BEAM crashes, manages Rust panics, and handles term encoding/decoding. Version 0.38.0 includes macros for mapping Rust structs and enums to Elixir types (Structs, Maps, Tuples, Records, and Atoms), support for dirty schedulers, and utilities for managing Erlang resources and environments via Env and OwnedEnv.

Tokens
6.1K
Snippets
23
Records
38
Agent score
89%

What's inside rustler

  1. Upgrade from 0.31 to 0.32

    master

    Key changes in version 0.32:

    1. rustler_bigint Integration: The functionality of rustler_bigint has moved into rustler. You can replace it by activating the big_integer feature on rustler. Note that rustler::BigInt is a re-export of num_bigint::BigInt, whereas rustler_bigint::BigInt was a wrapper. For most codebases, activate the feature and replace rustler_bigint::BigInt with rustler::BigInt (or num_bigint::BigInt).
    2. serde Integration: serde_rustler is now integrated into rustler via the serde feature flag. You can wrap serde-compatible objects in SerdeTerm to use them in place of Encoder or Decoder. This API is currently considered experimental.
  2. Migrate to `rustler::init!` and `rustler::nif` (v0.22+)

    master

    In version 0.22, the way NIFs are defined changed significantly.

    Replace rustler_export_nifs! with init!

    Instead of using tuple syntax to list NIFs and their arities, use rustler::init! with a list of function names. To define an on_load function, use the load argument.

    Use #[rustler::nif] for NIF declarations

    Instead of manually handling args: &[Term<'a>], use the #[rustler::nif] proc-macro. This allows you to define NIF signatures that resemble Elixir functions, using types that implement Decoder and Encoder.

    If you need the environment, you can explicitly include env: Env<'a> in the signature.

    Migrating Flags and Renaming

    NIF flags (like SchedulerFlags::DirtyCpu) and renames are now handled via arguments in the #[rustler::nif] macro rather than in the init! macro.

    // Before 0.22
    rustler::rustler_export_nifs! {
        "Elixir.SomeNif",
        [("_long_running_operation", 0, long_running_operation, SchedulerFlags::DirtyCpu)],
        None
    }
    
    fn long_running_operation<'a>(env: Env<'a>, _args: &[Term<'a>]) -> Result<Term<'a>, Error> {
      // ...
    }
    
    // Now (0.22+)
    rustler::init!("Elixir.SomeNif", [long_running_operation]);
    
    #[rustler::nif(
        rename = "_long_running_operation",
        schedule = "DirtyCpu"
      )]
    fn long_running_operation() -> TheProperReturnType {
      // ..
    }
  3. Get started with Rustler in Elixir

    master

    The recommended way to use Rustler is via the Elixir library. Follow these steps to set up a new NIF in your project:

    1. Add rustler as a dependency to your Elixir project.
    2. Run the Mix task mix rustler.new and follow the interactive instructions to generate the NIF boilerplate.
    3. If you use serde for data serialization, ensure you enable the serde feature in your NIF crate's Cargo.toml.
    mix rustler.new
  4. Upgrade from 0.33 to 0.34

    master

    Key changes in version 0.34:

    1. Automatic NIF Discovery: NIF implementations are now discovered automatically. Remove the argument listing NIFs from the rustler::init! macro. To prevent a NIF from being exported, use a #[cfg] marker.
    2. derive Feature: The derive feature is now unconditionally active. The feature flag is maintained for compatibility but will be removed.
    3. Resource Trait: To use a type as a resource, implement the Resource trait on the type. This allows specifying a destructor (taking an Env argument) or a down callback for process monitoring. Using the resource_impl attribute on the impl block will automatically register the type and set IMPLEMENTS_... constants for implemented callbacks.
  5. Upgrade from 0.34 to 0.35

    master
    In version 0.35, rustler_sys as a standalone library has been replaced by an embedded rustler::sys submodule. You cannot use the new rustler in conjunction with rustler_sys. Perform a simple textual replacement of rustler_sys with rustler::sys to migrate.
  6. Upgrade from 0.37 to 0.38

    master

    When upgrading to version 0.38, the following deprecated codegen features have been removed:

    • The resource! macro: replace it with resource_impl.
    • Explicit NIF function listing in the init! macro: remove the list of functions from the macro call.
  7. Upgrade from 0.30 to 0.31

    master

    Key changes in version 0.30:

    1. Configuration: rustler_crates configuration is deprecated. Use use Rustler options or configure the module in your config/*.exs files instead.
    2. Env::send and OwnedEnv::send_and_clear: These now return a Result. To avoid unused Result warnings without changing behavior, use: let _ = env.send(...);. Errors are returned if the receiving or sending process is dead.
    3. Term::get_type Changes: On non-Windows systems, Term::get_type uses enif_get_type. Changes include:
      • EmptyList is dropped; List is returned for both empty and non-empty lists.
      • Exception is dropped.
      • Number is split into Integer and Float (if NIF 2.14 support is enforced, only Float is returned).
    4. NIF Versioning: The default NIF version is 2.15. To use an older version (compatible with OTP < OTP22), disable default features and use nif_version_2_14 in Cargo.toml:
    rustler = { version = "0.30", default-features = false, features = ["derive", "nif_version_2_14"] }
    1. Environment Variables: The RUSTLER_NIF_VERSION environment variable is no longer used.
  8. Configure NIF version in Cargo.toml

    master

    By default, NIF libraries are compiled against NIF version 2.14 (compatible with OTP21). If you need to target a specific NIF version, such as 2.17 (which requires OTP26+), specify it in your Cargo.toml:

    [dependencies]
    rustler = { version = "0.30", features = ["nif_version_2_17"] }
  9. Configure NIF version features

    master

    Rustler allows you to target specific NIF versions by enabling corresponding Cargo features. The default is version 2.15 (Erlang/OTP 22). To use features from newer NIF versions, enable the specific feature flag in your Cargo.toml:

    • For NIF version 2.16 (Erlang/OTP 24), use nif_version_2_16.
    • For NIF version 2.17 (Erlang/OTP 26), use nif_version_2_17.
    [dependencies]
    rustler = { version = "...", features = ["nif_version_2_16"] }
  10. Write a minimal Rust NIF

    master

    To define a NIF, use the #[rustler::nif] attribute on your functions and initialize the module using rustler::init!. The following example demonstrates a simple addition NIF that can be called from Elixir module Math.

    #[rustler::nif]
    fn add(a: i64, b: i64) -> i64 {
        a + b
    }
    
    rustler::init!("Elixir.Math");