Function
Defining a JavaScript function is very simple in NAPI-RS. Just a plain Rust fn:
#[napi]
pub fn sum(a: u32, b: u32) -> u32 {
a + b
}
The most important thing you should keep in mind is NAPI-RS fn does not support every Rust type. Here is a table to illustrate how JavaScript types map to Rust types when they are fn arguments and return types:
Arguments
| Rust Type | JavaScript Type |
|---|---|
u32 |
number |
i32 |
number |
i64 |
number |
f64 |
number |
bool |
boolean |
String |
string |
Latin1String |
string |
UTF16String |
string |
#[napi(object)] struct |
Object |
& struct or &mut struct |
Class instance |
serde_json::Map |
Object |
serde_json::Value |
unknown |
std::collections::HashMap |
Object |
Array |
unknown[] |
Vec<T> T must be types in this table |
T[] |
Buffer |
Buffer |
External |
External |
Null |
null |
Undefined / () |
undefined |
Option<T> |
T or null |
Fn(Arg) ->T Arg and T must be types in this table |
(arg: Arg) => T |
Promise<T> |
Promise<T> |
AbortSignal |
AbortSignal |
JsSymbol |
Symbol |
Int8Array / Uint8Array / Int16Array... |
TypedArray |
BigInt |
BigInt |
Return Type
| Rust Type | JavaScript Type |
|---|---|
u32 |
number |
i32 |
number |
i64 |
number |
f64 |
number |
bool |
boolean |
String |
string |
Latin1String |
string |
UTF16String |
string |
#[napi(object)] struct |
Object |
#[napi] struct |
Class |
serde_json::Map |
Object |
serde_json::Value |
unknown |
std::collections::HashMap |
Object |
Array |
unknown[] |
Vec<T> T must be types in this table |
T[] |
Buffer |
Buffer |
External |
External |
Null |
null |
Undefined / () |
undefined |
Option<T> |
T or null |
AsyncTask<Task<JsValue = T>> |
Promise<T> |
JsSymbol |
Symbol |
Int8Array / Uint8Array / Int16Array... |
TypedArray |
BigInt |
BigInt |
i64n |
BigInt |
i128 |
BigInt |
u128 |
BigInt |
Function as parameter
You can pass a Function as a parameter to a fn:
use napi::bindgen_prelude::*;
use napi_derive::napi;
#[napi]
pub fn call_function(callback: Function<u32, u32>) -> Result<u32> {
callback.call(1)
}
⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️
export declare function callFunction(callback: (arg: number) => number): number
INFO
You can also create a Function at the Rust side, see Env::create_function
FnArgs
When the number of parameters exceeds 1, you can use FnArgs to define the parameters.
INFO
The tuple type can be converted to FnArgs by calling .into().
use napi::bindgen_prelude::*;
use napi_derive::napi;
#[napi]
pub fn call_function_with_args(callback: Function<FnArgs<(u32, u32)>, u32>) -> Result<u32> {
callback.call((1, 2).into())
}
⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️
export declare function callFunctionWithArgs(
callback: (arg1: number, arg2: number) => number,
): number
apply
Like JavaScript, you can also use apply to call a Function with the this value.
use napi::bindgen_prelude::*;
use napi_derive::napi;
#[napi]
pub struct RustClass {
pub name: String,
}
#[napi]
impl RustClass {
#[napi(constructor)]
pub fn new(name: String) -> Self {
Self { name }
}
}
#[napi]
pub fn call_function_with_apply(
this: ClassInstance<RustClass>,
callback: Function<(), ()>,
) -> Result<()> {
callback.apply(this, ())
}
import { callFunctionWithApply, RustClass } from './index.js'
const rustClass = new RustClass('foo')
callFunctionWithApply(rustClass, function () {
console.log(this.name) // foo
})
create_ref
See Function Reference for more details.
build_threadsafe_function
You can build a ThreadsafeFunction from a Function by calling build_threadsafe_function.
The return type of the build_threadsafe_function is a ThreadsafeFunctionBuilder.
By default, the ThreadsafeFunctionBuilder will create a ThreadsafeFunction with the default options:
INFO
See ThreadsafeFunction for the details of options
TIP
Since you can pass ThreadsafeFunction and Arc<ThreadsafeFunction> directly to the #[napi] fn, only use the build_threadsafe_function when you are need to create a ThreadsafeFunction dynamically.
max_queue_sizeis0weakisfalsecallee_handledistrueerror_statusisnapi::Status
use napi::{bindgen_prelude::*, threadsafe_function::ThreadsafeFunctionCallMode};
use napi_derive::napi;
#[napi]
pub fn build_threadsafe_function_from_function(
callback: Function<FnArgs<(u32, u32)>, u32>,
) -> Result<()> {
let tsfn = callback.build_threadsafe_function().build()?;
let jh = std::thread::spawn(move || {
tsfn.call((1, 2).into(), ThreadsafeFunctionCallMode::NonBlocking);
});
Ok(())
}