Changelog
View SourceAll notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
See UPGRADE.md for additional help when upgrading to newer
versions.
0.37.1 - 2025-09-10
Fixed
- Fix required Elixir version (>= 1.15) in
rustler_mix - Fix missing
chdirinrustler_mixwhen compiling in a subdirectory (#706)
0.37.0 - 2025-09-09
Added
- Add
staticlibfeature to compile withoutnif_initand add{pkg}_nif_initsymbol (#688) - Add
IntoIteratortoOwnedBinary(#702, thanks aDifferentJT)
Fixed
- Set
ErlNifEntry.min_ertsto a placeholder value (#703)
Changed
- Refactor build logic to remove TOML dependency (#691)
- Use
inlineon commonly used functions (#475, thanks @joshuataylor) - Make
EnifAllocatoravailable even if theallocatorfeature is not enabled
0.36.2 - 2025-06-09
Added
std::hash::Hashimplementation for atoms (#695)
Fixed
- Fix typing error in
rustler_mix(#696, thanks @dkuku)
0.36.1 - 2025-02-03
No changes in the Rust code, only rustler_mix adjustments and dependency
updates.
Added
- Support for Erlang-style NIF module names (
:module_name) (#682)
Fixed
- Retrieve the newest Rustler version without additional dependencies (#682, fixes #680)
- Adjust
.gitignorehandling to match the new workspace style
Changed
- Only depend on
libloadingon non-Windows systems (#677)
0.36.0 - 2025-01-13
Added
- Create a workplace
Cargo.tomlfile withmix rustler.new(#672)
Fixed
- Some derive macros failed when only
decodewas requested (#676)
Removed
- The linkage override for macOS is not needed anymore and has been removed from the template (#672)
[0.35.1] - 2024-12-18
Fixed
- Fix clippy lints in
rustler_codegen(#671) - Adjust
Rustlermacros to not produce warnings on Elixir 1.18 (#670)
[0.35.0] - 2024-10-15
Added
- The resource type name can be overridden with
#[register_impl(name = "...")](#638) - Floats can be decoded from integers (#641, fixes #603)
- Resource types can implement and use dynamic calls on NIF version 2.16 (#635)
EncoderandDecoderimplementations forBox<T>(#644)Referencetype andenv.make_ref()function (#657)
Fixed
- The optional
registerattribute on#[register_impl]works as advertised now (#638) - API functions for Windows are correctly assigned for NIF version 2.15 and above (#635)
- Panics in encoding the result of NIF function are caught (#656)
- Reverted change to "recompile if the NIF library is changed/deleted" (#654, fixes #651)
Changed
- The special ok/error handling for atoms in serde is now restricted to variant names (#639)
rustler_sysas a separate library is merged intorustler::sysand will not be released independently ofrustleranymore (#653)
[0.34.0] - 2024-07-09
Added
- Resource type registration has been refactored to eventually remove the
rustler::resource!macro (#617, necessary due to a pending deprecation of a Rust feature, #606) - Resources can (and should) now explicitly implement the new
Resourcetrait and provide a customdestructorfunction that is run beforedropand receives anEnvparameter (#617) - Process monitoring via resources can now be used on resource types that
implement the
Resource::downcallback (#617) - Resource implementation and registration helper attribute (#627)
Fixed
- Unwinding in the
on_loadcallback is now caught and leads to a panic (#617)
Changed
- NIF implementations are now discovered automatically and the respective
argument of
rustler::init!is ignored (#613) - The
derivefeature flag is now ignored and its functionality unconditionally enabled (#621)
[0.33.0] - 2024-05-29
Added
- Optional support for using Erlang's allocator as Rust's global allocator (#580).
- Comparison functions for PIDs (#611).
- Conversions from and to Rust paths (
PathBufandPath) (#608).
Fixed
mix compilefailing on path dependencies in the Rust library (#577, fixed in #578 and #607)
Changed
- Drop usage of
lazy_staticin favour ofstd::sync::OnceLock. This change raises the minimal supported Rust version to 1.70. - Drop obsolete and incorrect
Rustler.nif_versionsfunction.
Removed
- The old macros
rustler_export_nifs!,rustler::rustler_atoms!andresource_struct_init!have been removed (#604). They had been deprecated since version 0.22.0.
[0.32.1] - 2024-03-21
Added
- Map iterators are now DoubleEndedIterators
(#598), thus allowing being iterated in reverse using
.rev() Env::is_process_aliveandLocalPid::is_alive(#599)- Encoding and decoding of 128 bit integers (#600)
- Optional codec for
num_bigint::BigIntusing thebig_integerfeature (#601) - Add experimental
serdesupport derived fromserde_rustler
Changed
- Adjust C char types to use the proper FFI type (#592)
- Allow arbitrary (ASCII) NIF function names (#593, idea and initial implementation by @KoviRobi)
Removed
rustler_bigintis replaced by a feature flag and the wrapper is not necessary anymore (#601)
[0.32.0] - 2024-03-20
Yanked because it did not include all merged changes.
[0.31.0] - 2024-02-13
Added
- Support for generic types in derive macros (#574)
- New
is_floatandis_integermethods on terms (#581)
Fixed
- Finalized making
:rustlera compile-time-only dependency (#570) - Make
get_typework as documented for 0.30 (#581) - Tests on ARM64 (#584)
- Error messages in codegen (#579)
Changed
- Use
impl Encoderon more functions (in particular onsend) (#572) - The generated atom modules for derived structs are now called
rustler_atoms_{struct_name_in_snakecase}to silence warnings (#585)
Removed
- Support for
initmacroinrustler-sys(v2.3.2, #589)
[0.30.0] - 2023-10-11
Added
- Return
Result<(), SendError>from allsendfunctions (#239, #563)
Changed
- Deprecate
:rustler_cratesproject configuration - Mark
use Rustlermodule configuration as compile-time - Bump Rust edition to 2021
- Make
:rustlera compile-time-only dependency (#516, #559) - Use
enif_term_typeto implementTerm::get_type(#538). Please check theUPGRADEdocumentation for necessary code changes. - Raise default NIF version to 2.15
Removed
- Support for
RUSTLER_NIF_VERSION, NIF version requirements have to be set via features now
[0.29.1] - 2023-06-30
Fixed
- Exclude directories from external resources for compatibility with Elixir 1.15 (#548, thanks @adrienmo)
- Fix
NifTaggedEnumderivedEncoderimpl for named-field variants (#547, thanks @dylanburati) - Remove
cfg!directives in build.rs causing cross-compilation to fail (#555, thanks @fabriziosestito)
[0.29.0] - 2023-06-22
Added
ErlOption<T>to provide an ergonomic option type for Erlang (#507, thanks @tatsuya6502)
Changed
- Use Cargo features to define the NIF version level (#537), deprecating
RUSTLER_NIF_VERSION
[0.28.0] - 2023-04-24
Added
- Support OTP 26 (#526, thanks @philss)
- Support tuples in NIF macro (#520, #527, thanks @denumerate and @philss)
- Support for
load_data_funto computeload_dataat runtime (#413, thanks @kaaboaye)
Changed
- Enhanced NIF macro error messages for invalid attributes (#525, thanks @philss)
[0.27.0] - 2023-01-17
Added
ResourceArc::make_binaryfor safe use ofenif_make_resource_binary(#487)OwnedBinaryis nowSync(#493)- Specified MSRV to be 1.56.1.
Changed
MIX_ENVis no longer considered for determining the build profile. Now, the profile defaults to:release. Use the:modeoption to pick another profile explicitly. (#496)- Edition 2021 for the rustler mix template (#512, thanks @ayrat555)
Fixed
- Documentation for
load(#501, thanks @ishitatsuyuki)
[0.26.0] - 2022-09-02
Highlight
TaggedEnum
We added TaggedEnum, which is a generalized enum type (#440, thanks to
@SeokminHong!). Example:
#[derive(NifTaggedEnum)]
pub enum TaggedEnum1 {
Named { x: i32, y: i32 },
String1(String),
String2(String),
Untagged,
}On the Elixir side, the variants are represented as two-tuples {tag::atom(), inner::term()} | atom(), where the inner term is
- a map for the variant
Namedin the example above - a binary for the
String1andString2variants
The Untagged variant is represented as the atom :untagged in Elixir.
Added
- Added
CloneandCopyforTermType(#476, thanks @dvic) - Added
Env.whereis_pid()(#456, thanks @Qqwy)
Changed
- Use
&[impl Encoder]for keys and values inmap_from_arrays()to improve ergonomics (#453, thanks @SeokminHong) - Improved encode/decode performance of TaggedEnum considerably (#482, thanks @cleaton)
- Test on OTP 25 (#455)
Fixed
- Lifetime handling in
rustler_codegen(#483, thanks @turion @SeokminHong and @neosimsim) - Support multiple variants with same field names in TaggedEnum (#482, thanks @cleaton)
- Support .toml file extension for cargo config (#468, thanks @joshuataylor for the report in #467)
- Disambiguate
encode/decodein generated code (#466, thanks @SeokminHong) - Migrate CI to
erlef/setup-beam(#457, thanks @SeokminHong) - Documentation of the
scheduleflag fornifmacro (#444) - Improve documentation (#429, thanks @turion)
[0.25.0] - 2022-04-11
Added
NewBinarynow also available asrustler::NewBinary(thanks @ayrat555)Term::map_from_pairs()to conveniently build a map from a list of pairs (thanks @philss)- CI now also tests against macos
Fixed
- Snake-case warening for auto-generated
RUSTLER_{}_field_{}variables (renamed torustler_{}_field_{})
Changed
- Abort compilation on macos if macos target configuration is missing
[0.24.0] - 2022-02-24
Added
- A
NewBinarytype to create binaries in Rust without going throughOwnedBinary. This can improve performance. Thanks @dlesl! TermTypederivesEqandPartialEq.
Fixed
- Set library file extension based on the compile target, thanks @cocoa-xu!
- Relaxed Jason version requirement to ~> 1.0
- Various typos in the documentation, thanks @kianmeng!
Changed
- Rustler supports the latest 3 versions of Elixir and OTP. Currently, those are Elixir => 1.11 and OTP >= 22.
rustler_mix: Bumped required toml dependency to 0.6- Bumped
rustler_sysdependency to~2.2
[0.23.0] - 2021-12-22
Added
NifExceptionfor using Elixir exception structs- Hashing for term
- Hash and Equality for
BinaryandOwnedBinary
Fixed
mix rustler.newwith Elixir v1.13- Template config for
macos - Crash if metadata cannot be retrieved while compiling (#398)
Changed
- Rustler changed its supported range of OTP and Elixir versions. We aim to support the three newest versions of OTP and Elixir.
- The decoder for
Rangerequires that:stepequals1. The:stepfield was introduced with Elixir v1.12 and cannot be represented with Rust'sRangeInclusive. - NIF API bindings are generated using Rust
[0.22.2] - 2021-10-07
Fixed
- Fixed a regression introduced with #386:
Rustler.Compiler.Configcalled intocargowhenskip_compilation?was set, breaking setups where cargo is not installed. Fixed with #389, thanks @karolsluszniak
[0.22.1] - 2021-10-05
Fixed
- [Breaking change] codegen-generated decoders always raise an error instead of causing the calling NIF to return an atom in some cases
- Fix codegen problem for untagged enums (#370)
- Fix handling local dependencies with
@external_resources(#381)
[0.22.0] - 2021-06-22
Added
- Simple
Debugimpl forrustler::Error - Support newtype and tuple structs for
NifTupleandNifRecord rustler::Error::Termencoding an arbitrary boxed encoder, returning{:error, term}- Generic encoder/decoder for
HashMap<T, U>, whereT: DecoderandU: Decoder
Fixed
- Compilation time of generated decoders has been reduced significantly.
- Fixed a segfault caused by
OwnedEnv::send_and_clear
Changed
Renamed
PidtoLocalPidto clarify that it can't point to a remote processDependencies have been updated.
Derive macros have been refactored.
Macros have been renamed and old ones have been deprecated:
rustler_export_nifs!is nowrustler::init!rustler_atoms!is nowrustler::atoms!resource_struct_init!is nowrustler::resource!
New
rustler::atoms!macro removed theatomprefix from the name:// // Before // rustler::rustler_atoms! { atom ok; atom error; atom renamed_atom = "Renamed"; } // // After // rustler::atoms! { ok, error, renamed_atom = "Renamed", }NIF functions can be initialized with a simplified syntax:
// // Before // rustler::rustler_export_nifs! { "Elixir.Math", [ ("add", 2, add) ], None } // // After // rustler::init!("Elixir.Math", [add]);NIFs can be derived from regular functions, if the arguments implement
Decoderand the return type implementsEncoder:// // Before // fn add<'a>(env: Env<'a>, args: &[Term<'a>]) -> Result<Term<'a>, Error> { let num1: i64 = args[0].decode()?; let num2: i64 = args[1].decode()?; Ok((atoms::ok(), num1 + num2).encode(env)) } // // After // #[rustler::nif] fn add(a: i64, b: i64) -> i64 { a + b }rustler::nifexposes more options to configure a NIF were the NIF is defined:#[rustler::nif(schedule = "DirtyCpu")] pub fn dirty_cpu() -> Atom { let duration = Duration::from_millis(100); std::thread::sleep(duration); atoms::ok() } #[rustler::nif(name = "my_add")] fn add(a: i64, b: i64) -> i64 { a + b }
Deprecated
The rustler compiler has been deprecated and will be removed with v1.0. NIFs
are no longer defined in mix.exs, but are configured with use Rustler. See
the documentation for the Rustler module. To migrate to the new
configuration:
Drop
:rustlerfrom the:compilerskey in yourmix.exsproject/0functionDrop
:rustler_cratesfromproject/0and move the configurations into theuse Rustlerof your NIF module or application config:# config/dev.exs config :my_app, MyApp.Native, mode: :debug
For more information, see the documentation.
[0.21.0] - 2019-09-07
Added
- Support for OTP22.
- Rust linting with clippy.
- Support for decoding IOLists as binaries,
Term::decode_as_binary.
Changed
rustler_codegenis now reexported by therustlercrate. Depending on therustler_codegencrate is deprecated.erlang_nif-syshas been renamed torustler_sysand vendored into the rustler repo.- Replaced the hand-rolled TOML parser in
rustler_mixwith thetoml-elixirpackage. - Improve error messages for derived encoders/decoders.
- Rust
boolnow corresponds only to booleans (false,true) in Elixir. Previously,nilandfalsewere both decodable tobool. To use the previous behaviour, aTruthynewtype was introduced.