Skip to content

Commit

Permalink
Allow arbitrary ASCII strings as NIF names
Browse files Browse the repository at this point in the history
  • Loading branch information
filmor committed Feb 19, 2024
1 parent 2ae8765 commit 08c556d
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ versions.

### 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

## [0.31.0] - 2024-02-13
Expand Down
10 changes: 7 additions & 3 deletions rustler_codegen/src/nif.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,19 @@ pub fn transcoder_decorator(nif_attributes: NifAttributes, fun: syn::ItemFn) ->
let argument_names = create_function_params(inputs.clone());
let erl_func_name = nif_attributes
.custom_name
.map(|n| syn::Ident::new(n.value().as_str(), Span::call_site()))
.unwrap_or_else(|| name.clone());
.map(|n| n.value().to_string())
.unwrap_or_else(|| name.clone().to_string());

if !erl_func_name.is_ascii() {
panic!("Only ASCII strings are supported as function names");
}

quote! {
#[allow(non_camel_case_types)]
pub struct #name;

impl rustler::Nif for #name {
const NAME: *const rustler::codegen_runtime::c_char = concat!(stringify!(#erl_func_name), "\0").as_ptr() as *const rustler::codegen_runtime::c_char;
const NAME: *const rustler::codegen_runtime::c_char = concat!(#erl_func_name, "\0").as_ptr() as *const rustler::codegen_runtime::c_char;
const ARITY: rustler::codegen_runtime::c_uint = #arity;
const FLAGS: rustler::codegen_runtime::c_uint = #flags as rustler::codegen_runtime::c_uint;
const RAW_FUNC: unsafe extern "C" fn(
Expand Down
2 changes: 1 addition & 1 deletion rustler_tests/lib/rustler_test.ex
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ defmodule RustlerTest do
def raise_term_with_atom_error(), do: err()
def term_with_tuple_error(), do: err()

def nif_attrs_can_rename(), do: err()
def nif_attrs_can_rename!(), do: err()

def add_from_tuple(_tuple), do: err()
def add_one_to_tuple(_tuple), do: err()
Expand Down
2 changes: 1 addition & 1 deletion rustler_tests/native/rustler_test/src/test_nif_attrs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[rustler::nif(name = "nif_attrs_can_rename")]
#[rustler::nif(name = "nif_attrs_can_rename!")]
pub fn can_rename() -> bool {
true
}
2 changes: 1 addition & 1 deletion rustler_tests/test/nif_attrs_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ defmodule NifAttrsTest do
use ExUnit.Case

test "can rename a NIF with an attribute" do
assert RustlerTest.nif_attrs_can_rename()
assert RustlerTest.nif_attrs_can_rename!()
end
end

0 comments on commit 08c556d

Please sign in to comment.