$ show rusterlium/rustler
Rustler is a Rust library for writing safe, efficient Native Implemented Functions (NIFs) for the Erlang VM (BEAM), primarily used from Elixir. It provides a high-level, type-safe API that abstracts away the low-level C NIF interface, allowing developers to write NIFs in idiomatic Rust with automatic encoding/decoding of Erlang terms. The architecture consists of three main crates: `rustler` (core runtime and type system), `rustler_codegen` (procedural macros for NIF export and derive traits), and `rustler_mix` (Elixir Mix integration for building and loading NIFs). Key entry points include the `init!` macro to register NIFs, the `#[nif]` attribute macro to define functions, and derive macros like `NifStruct`, `NifMap`, and `NifTaggedEnum` for automatic term conversion. Data flows involve Rust functions receiving decoded Erlang terms (via the `Decoder` trait) and returning encoded terms (via the `Encoder` trait), with support for complex types, resources, threading, and serde serialization. External dependencies include the Erlang/OTP NIF API (dynamically loaded), the `inventory` crate for static registration, and optional `serde` and `num-bigint` crates.
The LLM identified 4 files worth highlighting for reuse:
Implements `ResourceArc<T>`, a thread-safe, reference-counted wrapper for Erlang NIF resources. It uses `Arc` internally and provides automatic cleanup via the `Drop` trait, ensuring resources are freed when the last reference is dropped. This pattern is reusable for any Rust library that needs to manage native resources across the BEAM boundary safely.
Provides `OwnedEnv` and `SavedTerm` for creating and sending messages from non-Erlang scheduler threads. This enables long-running or blocking operations to be offloaded to separate OS threads while still interacting with the BEAM. The pattern is reusable for any NIF library that needs to perform background work and communicate results back to Erlang processes.
Implements a `serde::Deserializer` for Erlang terms, allowing any Rust type that implements `serde::Deserialize` to be decoded from NIF arguments. It handles atoms, binaries, lists, maps, tuples, and nested structures, mapping them to serde's data model. This component is reusable for any project that needs to deserialize Erlang terms into Rust types using serde's derive mechanism.
Parses C header files from the Erlang OTP distribution to generate Rust FFI bindings for the NIF API. It extracts function signatures, handles platform-specific types, and produces versioned Rust source files. This pattern is reusable for any project that needs to automatically generate Rust bindings from C headers, especially when supporting multiple API versions.