feat(napi): implement all object functions
This commit is contained in:
parent
06da68df0e
commit
76d1258592
31 changed files with 520 additions and 207 deletions
|
@ -112,7 +112,7 @@ pub fn js_function(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|||
}
|
||||
|
||||
let mut env = Env::from_raw(raw_env);
|
||||
let call_ctx = CallContext::new(&mut env, raw_this, &raw_args, #arg_len_span, argc as usize);
|
||||
let call_ctx = CallContext::new(&mut env, cb_info, raw_this, &raw_args, #arg_len_span, argc as usize);
|
||||
let result = call_ctx.and_then(|ctx| {
|
||||
match panic::catch_unwind(AssertUnwindSafe(move || #new_fn_name(ctx))) {
|
||||
Ok(result) => result,
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
use std::ptr;
|
||||
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, Either, Env, Error, JsUndefined, JsUnknown, NapiValue, Result, Status};
|
||||
|
||||
pub struct CallContext<'env, T: NapiValue = JsUnknown> {
|
||||
pub env: &'env Env,
|
||||
pub this: T,
|
||||
callback_info: sys::napi_callback_info,
|
||||
args: &'env [sys::napi_value],
|
||||
arg_len: usize,
|
||||
actual_arg_length: usize,
|
||||
|
@ -12,6 +16,7 @@ impl<'env, T: NapiValue> CallContext<'env, T> {
|
|||
#[inline]
|
||||
pub fn new(
|
||||
env: &'env Env,
|
||||
callback_info: sys::napi_callback_info,
|
||||
this: sys::napi_value,
|
||||
args: &'env [sys::napi_value],
|
||||
arg_len: usize,
|
||||
|
@ -19,6 +24,7 @@ impl<'env, T: NapiValue> CallContext<'env, T> {
|
|||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
env,
|
||||
callback_info,
|
||||
this: T::from_raw(env.0, this)?,
|
||||
args,
|
||||
arg_len,
|
||||
|
@ -53,4 +59,13 @@ impl<'env, T: NapiValue> CallContext<'env, T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_new_target<V>(&self) -> Result<V>
|
||||
where
|
||||
V: NapiValue,
|
||||
{
|
||||
let mut value = ptr::null_mut();
|
||||
check_status(unsafe { sys::napi_get_new_target(self.env.0, self.callback_info, &mut value) })?;
|
||||
V::from_raw(self.env.0, value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -379,12 +379,12 @@ impl Env {
|
|||
&self,
|
||||
name: &str,
|
||||
constructor_cb: Callback,
|
||||
properties: Vec<Property>,
|
||||
properties: &mut [Property],
|
||||
) -> Result<JsFunction> {
|
||||
let mut raw_result = ptr::null_mut();
|
||||
let raw_properties = properties
|
||||
.into_iter()
|
||||
.map(|prop| prop.into_raw(self))
|
||||
.iter_mut()
|
||||
.map(|prop| prop.as_raw(self.0))
|
||||
.collect::<Result<Vec<sys::napi_property_descriptor>>>()?;
|
||||
|
||||
check_status(unsafe {
|
||||
|
|
|
@ -1,17 +1,41 @@
|
|||
use std::convert::From;
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
use crate::{sys, Callback, Env, NapiValue, Result};
|
||||
use crate::{error::check_status, sys, Callback, NapiValue, Result};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Property {
|
||||
name: String,
|
||||
raw_descriptor: sys::napi_property_descriptor,
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Property<'env> {
|
||||
name: &'env str,
|
||||
pub(crate) raw_descriptor: sys::napi_property_descriptor,
|
||||
}
|
||||
|
||||
impl Property {
|
||||
pub fn new(name: &str) -> Self {
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum PropertyAttributes {
|
||||
Default = sys::napi_property_attributes::napi_default as _,
|
||||
Writable = sys::napi_property_attributes::napi_writable as _,
|
||||
Enumerable = sys::napi_property_attributes::napi_enumerable as _,
|
||||
Configurable = sys::napi_property_attributes::napi_configurable as _,
|
||||
Static = sys::napi_property_attributes::napi_static as _,
|
||||
}
|
||||
|
||||
impl From<PropertyAttributes> for sys::napi_property_attributes {
|
||||
fn from(value: PropertyAttributes) -> Self {
|
||||
match value {
|
||||
PropertyAttributes::Default => sys::napi_property_attributes::napi_default,
|
||||
PropertyAttributes::Writable => sys::napi_property_attributes::napi_writable,
|
||||
PropertyAttributes::Enumerable => sys::napi_property_attributes::napi_enumerable,
|
||||
PropertyAttributes::Configurable => sys::napi_property_attributes::napi_configurable,
|
||||
PropertyAttributes::Static => sys::napi_property_attributes::napi_static,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'env> Property<'env> {
|
||||
pub fn new(name: &'env str) -> Self {
|
||||
Property {
|
||||
name: String::from(name),
|
||||
name,
|
||||
raw_descriptor: sys::napi_property_descriptor {
|
||||
utf8name: ptr::null_mut(),
|
||||
name: ptr::null_mut(),
|
||||
|
@ -40,8 +64,27 @@ impl Property {
|
|||
self
|
||||
}
|
||||
|
||||
pub(crate) fn into_raw(mut self, env: &Env) -> Result<sys::napi_property_descriptor> {
|
||||
self.raw_descriptor.name = env.create_string(&self.name)?.raw_value();
|
||||
pub fn with_setter(mut self, callback: Callback) -> Self {
|
||||
self.raw_descriptor.setter = Some(callback);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_property_attributes(mut self, attributes: PropertyAttributes) {
|
||||
self.raw_descriptor.attributes = attributes.into();
|
||||
}
|
||||
|
||||
pub(crate) fn as_raw(&mut self, env: sys::napi_env) -> Result<sys::napi_property_descriptor> {
|
||||
let string_value = CString::new(self.name)?;
|
||||
let mut result = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
sys::napi_create_string_utf8(
|
||||
env,
|
||||
string_value.as_ptr(),
|
||||
self.name.len() as _,
|
||||
&mut result,
|
||||
)
|
||||
})?;
|
||||
self.raw_descriptor.name = result;
|
||||
Ok(self.raw_descriptor)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ impl<'x, 'de, 'env> serde::de::Deserializer<'x> for &'de mut De<'env> {
|
|||
),
|
||||
))
|
||||
} else {
|
||||
let key = properties.get_index::<JsString>(0)?;
|
||||
let key = properties.get_element::<JsString>(0)?;
|
||||
let value: JsUnknown = js_object.get_property(&key)?;
|
||||
visitor.visit_enum(JsEnumAccess::new(key.as_str()?.to_owned(), Some(&value.0)))
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ impl<'de, 'env> SeqAccess<'de> for JsArrayAccess<'env> {
|
|||
if self.idx >= self.len {
|
||||
return Ok(None);
|
||||
}
|
||||
let v = self.input.get_index::<JsUnknown>(self.idx)?;
|
||||
let v = self.input.get_element::<JsUnknown>(self.idx)?;
|
||||
self.idx += 1;
|
||||
|
||||
let mut de = De(&v.0);
|
||||
|
@ -331,7 +331,7 @@ impl<'de, 'env> MapAccess<'de> for JsObjectAccess<'env> {
|
|||
return Ok(None);
|
||||
}
|
||||
|
||||
let prop_name = self.properties.get_index::<JsUnknown>(self.idx)?;
|
||||
let prop_name = self.properties.get_element::<JsUnknown>(self.idx)?;
|
||||
|
||||
let mut de = De(&prop_name.0);
|
||||
seed.deserialize(&mut de).map(Some)
|
||||
|
@ -347,7 +347,7 @@ impl<'de, 'env> MapAccess<'de> for JsObjectAccess<'env> {
|
|||
format!("Index:{} out of range: {}", self.property_len, self.idx),
|
||||
));
|
||||
}
|
||||
let prop_name = self.properties.get_index::<JsString>(self.idx)?;
|
||||
let prop_name = self.properties.get_element::<JsString>(self.idx)?;
|
||||
let value: JsUnknown = self.value.get_property(&prop_name)?;
|
||||
|
||||
self.idx += 1;
|
||||
|
|
|
@ -42,7 +42,7 @@ impl JsFunction {
|
|||
raw_args[i] = arg.0.value;
|
||||
}
|
||||
let mut return_value = ptr::null_mut();
|
||||
let status = unsafe {
|
||||
check_status(unsafe {
|
||||
sys::napi_call_function(
|
||||
self.0.env,
|
||||
raw_this,
|
||||
|
@ -51,8 +51,7 @@ impl JsFunction {
|
|||
&raw_args[0],
|
||||
&mut return_value,
|
||||
)
|
||||
};
|
||||
check_status(status)?;
|
||||
})?;
|
||||
|
||||
JsUnknown::from_raw(self.0.env, return_value)
|
||||
}
|
||||
|
|
|
@ -3,37 +3,35 @@ use std::ptr;
|
|||
|
||||
use super::Value;
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, Env, Error, JsBuffer, JsNumber, JsString, NapiValue, Result, Status};
|
||||
use crate::{sys, Error, JsString, NapiValue, Property, Result, Status};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JsObject(pub(crate) Value);
|
||||
|
||||
impl JsObject {
|
||||
pub fn set_property<V: NapiValue>(&mut self, key: JsString, value: V) -> Result<()> {
|
||||
let status =
|
||||
unsafe { sys::napi_set_property(self.0.env, self.0.value, key.0.value, value.raw_value()) };
|
||||
check_status(status)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_number_indexed_property<V: NapiValue>(
|
||||
&mut self,
|
||||
key: JsNumber,
|
||||
value: V,
|
||||
) -> Result<()> {
|
||||
pub fn set_property<V>(&mut self, key: JsString, value: V) -> Result<()>
|
||||
where
|
||||
V: NapiValue,
|
||||
{
|
||||
check_status(unsafe {
|
||||
sys::napi_set_property(self.0.env, self.0.value, key.0.value, value.raw_value())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_named_property<T: NapiValue>(&mut self, name: &str, value: T) -> Result<()> {
|
||||
pub fn set_named_property<T>(&mut self, name: &str, value: T) -> Result<()>
|
||||
where
|
||||
T: NapiValue,
|
||||
{
|
||||
let key = CString::new(name)?;
|
||||
check_status(unsafe {
|
||||
sys::napi_set_named_property(self.0.env, self.0.value, key.as_ptr(), value.raw_value())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_named_property<T: NapiValue>(&self, name: &str) -> Result<T> {
|
||||
pub fn get_named_property<T>(&self, name: &str) -> Result<T>
|
||||
where
|
||||
T: NapiValue,
|
||||
{
|
||||
let key = CString::new(name)?;
|
||||
let mut raw_value = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
|
@ -42,7 +40,66 @@ impl JsObject {
|
|||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
pub fn get_property<K: NapiValue, T: NapiValue>(&self, key: &K) -> Result<T> {
|
||||
pub fn has_named_property(&self, name: &str) -> Result<bool> {
|
||||
let mut result = false;
|
||||
let key = CString::new(name)?;
|
||||
check_status(unsafe {
|
||||
sys::napi_has_named_property(self.0.env, self.0.value, key.as_ptr(), &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn has_own_property(&self, key: &str) -> Result<bool> {
|
||||
let mut result = false;
|
||||
let string = CString::new(key)?;
|
||||
let mut js_key = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
sys::napi_create_string_utf8(self.0.env, string.as_ptr(), key.len() as _, &mut js_key)
|
||||
})?;
|
||||
check_status(unsafe {
|
||||
sys::napi_has_own_property(self.0.env, self.0.value, js_key, &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn has_own_property_js<K>(&self, key: K) -> Result<bool>
|
||||
where
|
||||
K: NapiValue,
|
||||
{
|
||||
let mut result = false;
|
||||
check_status(unsafe {
|
||||
sys::napi_has_own_property(self.0.env, self.0.value, key.raw_value(), &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn has_property(&self, name: &str) -> Result<bool> {
|
||||
let string = CString::new(name)?;
|
||||
let mut js_key = ptr::null_mut();
|
||||
let mut result = false;
|
||||
check_status(unsafe {
|
||||
sys::napi_create_string_utf8(self.0.env, string.as_ptr(), name.len() as _, &mut js_key)
|
||||
})?;
|
||||
check_status(unsafe { sys::napi_has_property(self.0.env, self.0.value, js_key, &mut result) })?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn has_property_js<K>(&self, name: K) -> Result<bool>
|
||||
where
|
||||
K: NapiValue,
|
||||
{
|
||||
let mut result = false;
|
||||
check_status(unsafe {
|
||||
sys::napi_has_property(self.0.env, self.0.value, name.raw_value(), &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn get_property<K, T>(&self, key: &K) -> Result<T>
|
||||
where
|
||||
K: NapiValue,
|
||||
T: NapiValue,
|
||||
{
|
||||
let mut raw_value = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
sys::napi_get_property(self.0.env, self.0.value, key.raw_value(), &mut raw_value)
|
||||
|
@ -50,18 +107,52 @@ impl JsObject {
|
|||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
pub fn get_property_names<T: NapiValue>(&self) -> Result<T> {
|
||||
pub fn get_property_names<T>(&self) -> Result<T>
|
||||
where
|
||||
T: NapiValue,
|
||||
{
|
||||
let mut raw_value = ptr::null_mut();
|
||||
let status = unsafe { sys::napi_get_property_names(self.0.env, self.0.value, &mut raw_value) };
|
||||
check_status(status)?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
pub fn set_index<T: NapiValue>(&mut self, index: usize, value: T) -> Result<()> {
|
||||
self.set_number_indexed_property(Env::from_raw(self.0.env).create_int64(index as i64)?, value)
|
||||
pub fn get_prototype<T>(&self) -> Result<T>
|
||||
where
|
||||
T: NapiValue,
|
||||
{
|
||||
let mut result = ptr::null_mut();
|
||||
check_status(unsafe { sys::napi_get_prototype(self.0.env, self.0.value, &mut result) })?;
|
||||
T::from_raw(self.0.env, result)
|
||||
}
|
||||
|
||||
pub fn get_index<T: NapiValue>(&self, index: u32) -> Result<T> {
|
||||
pub fn set_element<T>(&mut self, index: u32, value: T) -> Result<()>
|
||||
where
|
||||
T: NapiValue,
|
||||
{
|
||||
check_status(unsafe {
|
||||
sys::napi_set_element(self.0.env, self.0.value, index, value.raw_value())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn has_element(&self, index: u32) -> Result<bool> {
|
||||
let mut result = false;
|
||||
check_status(unsafe { sys::napi_has_element(self.0.env, self.0.value, index, &mut result) })?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn delete_element<T>(&mut self, index: u32) -> Result<bool> {
|
||||
let mut result = false;
|
||||
check_status(unsafe {
|
||||
sys::napi_delete_element(self.0.env, self.0.value, index, &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn get_element<T>(&self, index: u32) -> Result<T>
|
||||
where
|
||||
T: NapiValue,
|
||||
{
|
||||
let mut raw_value = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
sys::napi_get_element(self.0.env, self.0.value, index, &mut raw_value)
|
||||
|
@ -69,6 +160,21 @@ impl JsObject {
|
|||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
pub fn define_properties(&mut self, properties: &mut [Property]) -> Result<()> {
|
||||
check_status(unsafe {
|
||||
sys::napi_define_properties(
|
||||
self.0.env,
|
||||
self.0.value,
|
||||
properties.len() as _,
|
||||
properties
|
||||
.iter_mut()
|
||||
.map(|property| property.as_raw(self.0.env))
|
||||
.collect::<Result<Vec<sys::napi_property_descriptor>>>()?
|
||||
.as_ptr(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn is_array(&self) -> Result<bool> {
|
||||
let mut is_array = false;
|
||||
check_status(unsafe { sys::napi_is_array(self.0.env, self.0.value, &mut is_array) })?;
|
||||
|
@ -81,10 +187,6 @@ impl JsObject {
|
|||
Ok(is_buffer)
|
||||
}
|
||||
|
||||
pub fn to_buffer(&self) -> Result<JsBuffer> {
|
||||
JsBuffer::from_raw(self.0.env, self.0.value)
|
||||
}
|
||||
|
||||
pub fn get_array_length(&self) -> Result<u32> {
|
||||
if self.is_array()? != true {
|
||||
return Err(Error::new(
|
||||
|
|
|
@ -310,8 +310,8 @@ impl ser::SerializeSeq for SeqSerializer {
|
|||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.array.0.env);
|
||||
self.array.set_index(
|
||||
self.current_index,
|
||||
self.array.set_element(
|
||||
self.current_index as _,
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
self.current_index = self.current_index + 1;
|
||||
|
@ -334,8 +334,8 @@ impl ser::SerializeTuple for SeqSerializer {
|
|||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.array.0.env);
|
||||
self.array.set_index(
|
||||
self.current_index,
|
||||
self.array.set_element(
|
||||
self.current_index as _,
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
self.current_index = self.current_index + 1;
|
||||
|
@ -359,8 +359,8 @@ impl ser::SerializeTupleStruct for SeqSerializer {
|
|||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.array.0.env);
|
||||
self.array.set_index(
|
||||
self.current_index,
|
||||
self.array.set_element(
|
||||
self.current_index as _,
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
self.current_index = self.current_index + 1;
|
||||
|
@ -384,8 +384,8 @@ impl ser::SerializeTupleVariant for SeqSerializer {
|
|||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.array.0.env);
|
||||
self.array.set_index(
|
||||
self.current_index,
|
||||
self.array.set_element(
|
||||
self.current_index as _,
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
self.current_index = self.current_index + 1;
|
||||
|
|
39
test_module/__test__/object.spec.ts
Normal file
39
test_module/__test__/object.spec.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import test from 'ava'
|
||||
|
||||
const bindings = require('../index.node')
|
||||
|
||||
test('setProperty', (t) => {
|
||||
const obj = {}
|
||||
const key = 'jsPropertyKey'
|
||||
bindings.testSetProperty(obj, key)
|
||||
t.snapshot(obj[key])
|
||||
})
|
||||
|
||||
test('setNamedProperty', (t) => {
|
||||
const obj = {}
|
||||
const property = Symbol('JsSymbol')
|
||||
bindings.testSetNamedProperty(obj, property)
|
||||
const keys = Object.keys(obj)
|
||||
const [key] = keys
|
||||
t.is(keys.length, 1)
|
||||
t.snapshot(key)
|
||||
t.is(obj[key], property)
|
||||
})
|
||||
|
||||
test('testGetNamedProperty', (t) => {
|
||||
const obj = {
|
||||
p: Symbol('JsSymbol'),
|
||||
}
|
||||
t.is(bindings.testGetNamedProperty(obj), obj.p)
|
||||
})
|
||||
|
||||
test('testHasNamedProperty', (t) => {
|
||||
const obj = {
|
||||
a: 1,
|
||||
b: undefined,
|
||||
}
|
||||
|
||||
t.true(bindings.testHasNamedProperty(obj, 'a'))
|
||||
t.true(bindings.testHasNamedProperty(obj, 'b'))
|
||||
t.false(bindings.testHasNamedProperty(obj, 'c'))
|
||||
})
|
17
test_module/__test__/object.spec.ts.md
Normal file
17
test_module/__test__/object.spec.ts.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Snapshot report for `test_module/__test__/object.spec.ts`
|
||||
|
||||
The actual snapshot is saved in `object.spec.ts.snap`.
|
||||
|
||||
Generated by [AVA](https://avajs.dev).
|
||||
|
||||
## setProperty
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
'Rust object property'
|
||||
|
||||
## setNamedProperty
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
'RustPropertyKey'
|
BIN
test_module/__test__/object.spec.ts.snap
Normal file
BIN
test_module/__test__/object.spec.ts.snap
Normal file
Binary file not shown.
|
@ -1,6 +1,6 @@
|
|||
use std::str;
|
||||
|
||||
use napi::{CallContext, Error, JsBuffer, JsNumber, JsString, Result, Status};
|
||||
use napi::{CallContext, Error, JsBuffer, JsNumber, JsString, Module, Result, Status};
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn get_buffer_length(ctx: CallContext) -> Result<JsNumber> {
|
||||
|
@ -15,3 +15,9 @@ pub fn buffer_to_string(ctx: CallContext) -> Result<JsString> {
|
|||
str::from_utf8(&buffer).map_err(|e| Error::new(Status::StringExpected, format!("{}", e)))?,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("getBufferLength", get_buffer_length)?;
|
||||
module.create_named_method("bufferToString", buffer_to_string)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use napi::{CallContext, JsFunction, JsNumber, JsObject, JsUndefined, Property, Result};
|
||||
use napi::{CallContext, JsFunction, JsNumber, JsObject, JsUndefined, Module, Property, Result};
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn create_test_class(ctx: CallContext) -> Result<JsFunction> {
|
||||
fn create_test_class(ctx: CallContext) -> Result<JsFunction> {
|
||||
let add_count_method = Property::new("addCount").with_method(add_count);
|
||||
let properties = vec![add_count_method];
|
||||
ctx
|
||||
.env
|
||||
.define_class("TestClass", test_class_constructor, properties)
|
||||
let mut properties = vec![add_count_method];
|
||||
ctx.env.define_class(
|
||||
"TestClass",
|
||||
test_class_constructor,
|
||||
properties.as_mut_slice(),
|
||||
)
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn test_class_constructor(mut ctx: CallContext<JsObject>) -> Result<JsUndefined> {
|
||||
fn test_class_constructor(mut ctx: CallContext<JsObject>) -> Result<JsUndefined> {
|
||||
let count = ctx.get::<JsNumber>(0)?;
|
||||
ctx
|
||||
.this
|
||||
|
@ -21,7 +23,7 @@ pub fn test_class_constructor(mut ctx: CallContext<JsObject>) -> Result<JsUndefi
|
|||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn add_count(mut ctx: CallContext<JsObject>) -> Result<JsUndefined> {
|
||||
fn add_count(mut ctx: CallContext<JsObject>) -> Result<JsUndefined> {
|
||||
let add: i32 = ctx.get::<JsNumber>(0)?.try_into()?;
|
||||
let count: i32 = ctx
|
||||
.this
|
||||
|
@ -32,3 +34,8 @@ pub fn add_count(mut ctx: CallContext<JsObject>) -> Result<JsUndefined> {
|
|||
.set_named_property("count", ctx.env.create_int32(count + add)?)?;
|
||||
ctx.env.get_undefined()
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("createTestClass", create_test_class)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use napi::{CallContext, Either, JsNumber, JsString, Result};
|
||||
use napi::{CallContext, Either, JsNumber, JsString, Module, Result};
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn either_number_string(ctx: CallContext) -> Result<Either<JsNumber, JsString>> {
|
||||
|
@ -27,3 +27,9 @@ pub fn dynamic_argument_length(ctx: CallContext) -> Result<JsNumber> {
|
|||
ctx.env.create_uint32(42)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("eitherNumberString", either_number_string)?;
|
||||
module.create_named_method("dynamicArgumentLength", dynamic_argument_length)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
35
test_module/src/env.rs
Normal file
35
test_module/src/env.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use napi::{CallContext, JsBoolean, JsUnknown, Module, Result};
|
||||
|
||||
#[js_function(2)]
|
||||
pub fn instanceof(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let object = ctx.get::<JsUnknown>(0)?;
|
||||
let constructor = ctx.get::<JsUnknown>(1)?;
|
||||
ctx.env.get_boolean(object.instanceof(constructor)?)
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn is_typedarray(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let js_value = ctx.get::<JsUnknown>(0)?;
|
||||
ctx.env.get_boolean(js_value.is_typedarray()?)
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn is_dataview(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let js_value = ctx.get::<JsUnknown>(0)?;
|
||||
ctx.env.get_boolean(js_value.is_dataview()?)
|
||||
}
|
||||
|
||||
#[js_function(2)]
|
||||
pub fn strict_equals(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let a: JsUnknown = ctx.get(0)?;
|
||||
let b: JsUnknown = ctx.get(1)?;
|
||||
ctx.env.get_boolean(ctx.env.strict_equals(a, b)?)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("instanceof", instanceof)?;
|
||||
module.create_named_method("isTypedarray", is_typedarray)?;
|
||||
module.create_named_method("isDataview", is_dataview)?;
|
||||
module.create_named_method("strictEquals", strict_equals)?;
|
||||
Ok(())
|
||||
}
|
33
test_module/src/error.rs
Normal file
33
test_module/src/error.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
use napi::{CallContext, Error, JsBoolean, JsString, JsUnknown, Module, Result, Status};
|
||||
|
||||
#[js_function]
|
||||
fn test_throw(_ctx: CallContext) -> Result<JsUnknown> {
|
||||
Err(Error::from_status(Status::GenericFailure))
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
fn test_throw_with_reason(ctx: CallContext) -> Result<JsUnknown> {
|
||||
let reason = ctx.get::<JsString>(0)?;
|
||||
Err(Error::new(
|
||||
Status::GenericFailure,
|
||||
reason.as_str()?.to_owned(),
|
||||
))
|
||||
}
|
||||
|
||||
#[js_function]
|
||||
pub fn test_throw_with_panic(_ctx: CallContext) -> Result<JsUnknown> {
|
||||
panic!("don't panic.");
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn is_error(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let js_value = ctx.get::<JsUnknown>(0)?;
|
||||
ctx.env.get_boolean(js_value.is_error()?)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("testThrow", test_throw)?;
|
||||
module.create_named_method("testThrowWithReason", test_throw_with_reason)?;
|
||||
module.create_named_method("isError", is_error)?;
|
||||
Ok(())
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use napi::{CallContext, JsExternal, JsNumber, Result};
|
||||
use napi::{CallContext, JsExternal, JsNumber, Module, Result};
|
||||
|
||||
struct NativeObject {
|
||||
count: i32,
|
||||
|
@ -19,3 +19,9 @@ pub fn get_external_count(ctx: CallContext) -> Result<JsNumber> {
|
|||
let native_object = ctx.env.get_value_external::<NativeObject>(&attached_obj)?;
|
||||
ctx.env.create_int32(native_object.count)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("createExternal", create_external)?;
|
||||
module.create_named_method("getExternalCount", get_external_count)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use napi::{CallContext, JsFunction, JsNull, JsObject, Result};
|
||||
use napi::{CallContext, JsFunction, JsNull, JsObject, Module, Result};
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn call_function(ctx: CallContext) -> Result<JsNull> {
|
||||
|
@ -20,3 +20,9 @@ pub fn call_function_with_this(ctx: CallContext<JsObject>) -> Result<JsNull> {
|
|||
|
||||
ctx.env.get_null()
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("testCallFunction", call_function)?;
|
||||
module.create_named_method("testCallFunctionWithThis", call_function_with_this)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ extern crate napi_derive;
|
|||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
use napi::{CallContext, Error, JsBoolean, JsString, JsUnknown, Module, Result, Status};
|
||||
use napi::{Module, Result};
|
||||
|
||||
#[cfg(napi4)]
|
||||
mod libuv;
|
||||
|
@ -21,142 +21,44 @@ mod tokio_rt;
|
|||
mod buffer;
|
||||
mod class;
|
||||
mod either;
|
||||
mod env;
|
||||
mod error;
|
||||
mod external;
|
||||
mod function;
|
||||
mod napi_version;
|
||||
mod object;
|
||||
mod serde;
|
||||
mod string;
|
||||
mod symbol;
|
||||
mod task;
|
||||
|
||||
use buffer::{buffer_to_string, get_buffer_length};
|
||||
use either::{dynamic_argument_length, either_number_string};
|
||||
use external::{create_external, get_external_count};
|
||||
use function::{call_function, call_function_with_this};
|
||||
#[cfg(napi4)]
|
||||
use libuv::read_file::uv_read_file;
|
||||
#[cfg(napi4)]
|
||||
use napi4::{test_threadsafe_function, test_tokio_readfile, test_tsfn_error};
|
||||
#[cfg(napi5)]
|
||||
use napi5::is_date::test_object_is_date;
|
||||
#[cfg(napi6)]
|
||||
use napi6::bigint::{
|
||||
test_create_bigint_from_i128, test_create_bigint_from_i64, test_create_bigint_from_u128,
|
||||
test_create_bigint_from_u64, test_create_bigint_from_words, test_get_bigint_i64,
|
||||
test_get_bigint_u64, test_get_bigint_words,
|
||||
};
|
||||
use napi_version::get_napi_version;
|
||||
use symbol::{create_named_symbol, create_symbol_from_js_string, create_unnamed_symbol};
|
||||
use task::test_spawn_thread;
|
||||
#[cfg(napi4)]
|
||||
use tokio_rt::{error_from_tokio_future, test_execute_tokio_readfile};
|
||||
|
||||
register_module!(test_module, init);
|
||||
|
||||
fn init(module: &mut Module) -> Result<()> {
|
||||
serde::register_serde_func(module)?;
|
||||
module.create_named_method("testThrow", test_throw)?;
|
||||
module.create_named_method("testThrowWithReason", test_throw_with_reason)?;
|
||||
module.create_named_method("testSpawnThread", test_spawn_thread)?;
|
||||
module.create_named_method("createExternal", create_external)?;
|
||||
module.create_named_method("getExternalCount", get_external_count)?;
|
||||
module.create_named_method("getBufferLength", get_buffer_length)?;
|
||||
module.create_named_method("bufferToString", buffer_to_string)?;
|
||||
module.create_named_method("createNamedSymbol", create_named_symbol)?;
|
||||
module.create_named_method("createUnnamedSymbol", create_unnamed_symbol)?;
|
||||
module.create_named_method("createSymbolFromJsString", create_symbol_from_js_string)?;
|
||||
module.create_named_method("getNapiVersion", get_napi_version)?;
|
||||
module.create_named_method("testCallFunction", call_function)?;
|
||||
module.create_named_method("testCallFunctionWithThis", call_function_with_this)?;
|
||||
module.create_named_method("eitherNumberString", either_number_string)?;
|
||||
module.create_named_method("dynamicArgumentLength", dynamic_argument_length)?;
|
||||
module.create_named_method("createTestClass", class::create_test_class)?;
|
||||
module.create_named_method("concatString", string::concat_string)?;
|
||||
module.create_named_method("instanceof", instanceof)?;
|
||||
module.create_named_method("isError", is_error)?;
|
||||
module.create_named_method("isTypedarray", is_typedarray)?;
|
||||
module.create_named_method("isDataview", is_dataview)?;
|
||||
module.create_named_method("strictEquals", strict_equals)?;
|
||||
error::register_js(module)?;
|
||||
string::register_js(module)?;
|
||||
serde::register_js(module)?;
|
||||
task::register_js(module)?;
|
||||
external::register_js(module)?;
|
||||
buffer::register_js(module)?;
|
||||
either::register_js(module)?;
|
||||
symbol::register_js(module)?;
|
||||
function::register_js(module)?;
|
||||
class::register_js(module)?;
|
||||
env::register_js(module)?;
|
||||
object::register_js(module)?;
|
||||
#[cfg(napi4)]
|
||||
module.create_named_method("testExecuteTokioReadfile", test_execute_tokio_readfile)?;
|
||||
napi4::register_js(module)?;
|
||||
#[cfg(napi4)]
|
||||
module.create_named_method("testTsfnError", test_tsfn_error)?;
|
||||
tokio_rt::register_js(module)?;
|
||||
#[cfg(napi4)]
|
||||
module.create_named_method("testThreadsafeFunction", test_threadsafe_function)?;
|
||||
#[cfg(napi4)]
|
||||
module.create_named_method("testTokioReadfile", test_tokio_readfile)?;
|
||||
#[cfg(napi4)]
|
||||
module.create_named_method("testTokioError", error_from_tokio_future)?;
|
||||
#[cfg(napi4)]
|
||||
module.create_named_method("uvReadFile", uv_read_file)?;
|
||||
libuv::read_file::register_js(module)?;
|
||||
#[cfg(napi5)]
|
||||
module.create_named_method("testObjectIsDate", test_object_is_date)?;
|
||||
napi5::register_js(module)?;
|
||||
#[cfg(napi6)]
|
||||
module.create_named_method("testCreateBigintFromI64", test_create_bigint_from_i64)?;
|
||||
#[cfg(napi6)]
|
||||
module.create_named_method("testCreateBigintFromU64", test_create_bigint_from_u64)?;
|
||||
#[cfg(napi6)]
|
||||
module.create_named_method("testCreateBigintFromI128", test_create_bigint_from_i128)?;
|
||||
#[cfg(napi6)]
|
||||
module.create_named_method("testCreateBigintFromU128", test_create_bigint_from_u128)?;
|
||||
#[cfg(napi6)]
|
||||
module.create_named_method("testCreateBigintFromWords", test_create_bigint_from_words)?;
|
||||
#[cfg(napi6)]
|
||||
module.create_named_method("testGetBigintI64", test_get_bigint_i64)?;
|
||||
#[cfg(napi6)]
|
||||
module.create_named_method("testGetBigintU64", test_get_bigint_u64)?;
|
||||
#[cfg(napi6)]
|
||||
module.create_named_method("testGetBigintWords", test_get_bigint_words)?;
|
||||
napi6::register_js(module)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[js_function]
|
||||
fn test_throw(_ctx: CallContext) -> Result<JsUnknown> {
|
||||
Err(Error::from_status(Status::GenericFailure))
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
fn test_throw_with_reason(ctx: CallContext) -> Result<JsUnknown> {
|
||||
let reason = ctx.get::<JsString>(0)?;
|
||||
Err(Error::new(
|
||||
Status::GenericFailure,
|
||||
reason.as_str()?.to_owned(),
|
||||
))
|
||||
}
|
||||
|
||||
#[js_function]
|
||||
pub fn test_throw_with_panic(_ctx: CallContext) -> Result<JsUnknown> {
|
||||
panic!("don't panic.");
|
||||
}
|
||||
|
||||
#[js_function(2)]
|
||||
pub fn instanceof(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let object = ctx.get::<JsUnknown>(0)?;
|
||||
let constructor = ctx.get::<JsUnknown>(1)?;
|
||||
ctx.env.get_boolean(object.instanceof(constructor)?)
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn is_error(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let js_value = ctx.get::<JsUnknown>(0)?;
|
||||
ctx.env.get_boolean(js_value.is_error()?)
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn is_typedarray(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let js_value = ctx.get::<JsUnknown>(0)?;
|
||||
ctx.env.get_boolean(js_value.is_typedarray()?)
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn is_dataview(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let js_value = ctx.get::<JsUnknown>(0)?;
|
||||
ctx.env.get_boolean(js_value.is_dataview()?)
|
||||
}
|
||||
|
||||
#[js_function(2)]
|
||||
pub fn strict_equals(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let a: JsUnknown = ctx.get(0)?;
|
||||
let b: JsUnknown = ctx.get(1)?;
|
||||
ctx.env.get_boolean(ctx.env.strict_equals(a, b)?)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use std::thread;
|
||||
use std::fs;
|
||||
use std::thread;
|
||||
|
||||
use futures::prelude::*;
|
||||
use futures::channel::oneshot;
|
||||
use napi::{CallContext, Result, JsString, JsObject, Status, Error};
|
||||
use futures::prelude::*;
|
||||
use napi::{CallContext, Error, JsObject, JsString, Module, Result, Status};
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn uv_read_file(ctx: CallContext) -> Result<JsObject> {
|
||||
|
@ -14,7 +14,15 @@ pub fn uv_read_file(ctx: CallContext) -> Result<JsObject> {
|
|||
let res = fs::read(p).map_err(|e| Error::new(Status::Unknown, format!("{}", e)));
|
||||
sender.send(res).expect("Send data failed");
|
||||
});
|
||||
ctx.env.execute(receiver.map_err(|e| Error::new(Status::Unknown, format!("{}", e))).map(|x| x.and_then(|x| x)), |&mut env, data| {
|
||||
env.create_buffer_with_data(data)
|
||||
})
|
||||
ctx.env.execute(
|
||||
receiver
|
||||
.map_err(|e| Error::new(Status::Unknown, format!("{}", e)))
|
||||
.map(|x| x.and_then(|x| x)),
|
||||
|&mut env, data| env.create_buffer_with_data(data),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("uvReadFile", uv_read_file)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
use napi::{Module, Result};
|
||||
|
||||
mod tsfn;
|
||||
|
||||
pub use tsfn::*;
|
||||
use tsfn::*;
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("testTsfnError", test_tsfn_error)?;
|
||||
module.create_named_method("testThreadsafeFunction", test_threadsafe_function)?;
|
||||
module.create_named_method("testTokioReadfile", test_tokio_readfile)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1 +1,8 @@
|
|||
pub mod is_date;
|
||||
use napi::{Module, Result};
|
||||
|
||||
mod date;
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("testObjectIsDate", date::test_object_is_date)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -49,13 +49,7 @@ pub fn test_get_bigint_words(ctx: CallContext) -> Result<JsObject> {
|
|||
.create_bigint_from_words(true, vec![i64::max_value() as u64, i64::max_value() as u64])?;
|
||||
let mut js_arr = ctx.env.create_array_with_length(2)?;
|
||||
let (_signed, words) = js_bigint.get_words()?;
|
||||
js_arr.set_number_indexed_property(
|
||||
ctx.env.create_int64(0)?,
|
||||
ctx.env.create_bigint_from_u64(words[0])?,
|
||||
)?;
|
||||
js_arr.set_number_indexed_property(
|
||||
ctx.env.create_int64(1)?,
|
||||
ctx.env.create_bigint_from_u64(words[1])?,
|
||||
)?;
|
||||
js_arr.set_element(0, ctx.env.create_bigint_from_u64(words[0])?)?;
|
||||
js_arr.set_element(1, ctx.env.create_bigint_from_u64(words[1])?)?;
|
||||
Ok(js_arr)
|
||||
}
|
||||
|
|
|
@ -1 +1,17 @@
|
|||
pub mod bigint;
|
||||
use napi::{Module, Result};
|
||||
|
||||
mod bigint;
|
||||
|
||||
use bigint::*;
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("testCreateBigintFromI64", test_create_bigint_from_i64)?;
|
||||
module.create_named_method("testCreateBigintFromU64", test_create_bigint_from_u64)?;
|
||||
module.create_named_method("testCreateBigintFromI128", test_create_bigint_from_i128)?;
|
||||
module.create_named_method("testCreateBigintFromU128", test_create_bigint_from_u128)?;
|
||||
module.create_named_method("testCreateBigintFromWords", test_create_bigint_from_words)?;
|
||||
module.create_named_method("testGetBigintI64", test_get_bigint_i64)?;
|
||||
module.create_named_method("testGetBigintU64", test_get_bigint_u64)?;
|
||||
module.create_named_method("testGetBigintWords", test_get_bigint_words)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
38
test_module/src/object.rs
Normal file
38
test_module/src/object.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use napi::{CallContext, JsBoolean, JsObject, JsString, JsUndefined, JsUnknown, Module, Result};
|
||||
|
||||
#[js_function(2)]
|
||||
fn test_set_property(ctx: CallContext) -> Result<JsUndefined> {
|
||||
let mut obj = ctx.get::<JsObject>(0)?;
|
||||
let key = ctx.get::<JsString>(1)?;
|
||||
obj.set_property(key, ctx.env.create_string("Rust object property")?)?;
|
||||
ctx.env.get_undefined()
|
||||
}
|
||||
|
||||
#[js_function(2)]
|
||||
fn test_set_named_property(ctx: CallContext) -> Result<JsUndefined> {
|
||||
let mut obj = ctx.get::<JsObject>(0)?;
|
||||
let property = ctx.get::<JsUnknown>(1)?;
|
||||
obj.set_named_property("RustPropertyKey", property)?;
|
||||
ctx.env.get_undefined()
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
fn test_get_named_property(ctx: CallContext) -> Result<JsUnknown> {
|
||||
let obj = ctx.get::<JsObject>(0)?;
|
||||
obj.get_named_property("p")
|
||||
}
|
||||
|
||||
#[js_function(2)]
|
||||
fn test_has_named_property(ctx: CallContext) -> Result<JsBoolean> {
|
||||
let obj = ctx.get::<JsObject>(0)?;
|
||||
let key = ctx.get::<JsString>(1)?;
|
||||
ctx.env.get_boolean(obj.has_named_property(key.as_str()?)?)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("testSetProperty", test_set_property)?;
|
||||
module.create_named_method("testSetNamedProperty", test_set_named_property)?;
|
||||
module.create_named_method("testGetNamedProperty", test_get_named_property)?;
|
||||
module.create_named_method("testHasNamedProperty", test_has_named_property)?;
|
||||
Ok(())
|
||||
}
|
|
@ -162,7 +162,7 @@ fn roundtrip_object(ctx: CallContext) -> Result<JsUnknown> {
|
|||
ctx.env.to_js_value(&de_serialized)
|
||||
}
|
||||
|
||||
pub fn register_serde_func(m: &mut Module) -> Result<()> {
|
||||
pub fn register_js(m: &mut Module) -> Result<()> {
|
||||
m.create_named_method("make_num_77", make_num_77)?;
|
||||
m.create_named_method("make_num_32", make_num_32)?;
|
||||
m.create_named_method("make_str_hello", make_str_hello)?;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use napi::{CallContext, JsString, Result};
|
||||
use napi::{CallContext, JsString, Module, Result};
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn concat_string(ctx: CallContext) -> Result<JsString> {
|
||||
|
@ -6,3 +6,8 @@ pub fn concat_string(ctx: CallContext) -> Result<JsString> {
|
|||
let out_string = format!("{} + Rust 🦀 string!", in_string.as_str()?);
|
||||
ctx.env.create_string_from_std(out_string)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("concatString", concat_string)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use napi::{CallContext, JsString, JsSymbol, Result};
|
||||
use napi::{CallContext, JsString, JsSymbol, Module, Result};
|
||||
|
||||
#[js_function]
|
||||
pub fn create_named_symbol(ctx: CallContext) -> Result<JsSymbol> {
|
||||
|
@ -15,3 +15,10 @@ pub fn create_symbol_from_js_string(ctx: CallContext) -> Result<JsSymbol> {
|
|||
let name = ctx.get::<JsString>(0)?;
|
||||
ctx.env.create_symbol_from_js_string(name)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("createNamedSymbol", create_named_symbol)?;
|
||||
module.create_named_method("createUnnamedSymbol", create_unnamed_symbol)?;
|
||||
module.create_named_method("createSymbolFromJsString", create_symbol_from_js_string)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use napi::{CallContext, Env, JsNumber, JsObject, Result, Task};
|
||||
use napi::{CallContext, Env, JsNumber, JsObject, Module, Result, Task};
|
||||
|
||||
struct ComputeFib {
|
||||
n: u32,
|
||||
|
@ -34,8 +34,13 @@ fn fibonacci_native(n: u32) -> u32 {
|
|||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn test_spawn_thread(ctx: CallContext) -> Result<JsObject> {
|
||||
fn test_spawn_thread(ctx: CallContext) -> Result<JsObject> {
|
||||
let n = ctx.get::<JsNumber>(0)?;
|
||||
let task = ComputeFib::new(n.try_into()?);
|
||||
ctx.env.spawn(task)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("testSpawnThread", test_spawn_thread)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
use napi::{Module, Result};
|
||||
|
||||
mod read_file;
|
||||
|
||||
pub use read_file::*;
|
||||
use read_file::*;
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("testExecuteTokioReadfile", test_execute_tokio_readfile)?;
|
||||
module.create_named_method("testTokioError", error_from_tokio_future)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue