commit
973d3ee008
15 changed files with 440 additions and 239 deletions
|
@ -494,10 +494,10 @@ impl Env {
|
|||
result
|
||||
}
|
||||
|
||||
pub fn get_global(&self) -> Result<JsObject> {
|
||||
pub fn get_global(&self) -> Result<JsGlobal> {
|
||||
let mut raw_global = ptr::null_mut();
|
||||
check_status(unsafe { sys::napi_get_global(self.0, &mut raw_global) })?;
|
||||
Ok(JsObject::from_raw_unchecked(self.0, raw_global))
|
||||
Ok(JsGlobal::from_raw_unchecked(self.0, raw_global))
|
||||
}
|
||||
|
||||
pub fn get_napi_version(&self) -> Result<u32> {
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::ptr;
|
|||
|
||||
use super::Value;
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, JsUnknown, Ref, Result};
|
||||
use crate::{sys, JsUnknown, NapiValue, Ref, Result};
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
@ -49,8 +49,8 @@ impl JsArrayBufferValue {
|
|||
self.value
|
||||
}
|
||||
|
||||
pub fn into_unknown(self) -> Result<JsUnknown> {
|
||||
self.value.into_unknown()
|
||||
pub fn into_unknown(self) -> JsUnknown {
|
||||
JsUnknown::from_raw_unchecked(self.value.0.env, self.value.0.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use super::Value;
|
|||
#[cfg(feature = "serde-json")]
|
||||
use super::ValueType;
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, JsUnknown, Ref, Result};
|
||||
use crate::{sys, JsUnknown, NapiValue, Ref, Result};
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
@ -68,8 +68,8 @@ impl JsBufferValue {
|
|||
self.value
|
||||
}
|
||||
|
||||
pub fn into_unknown(self) -> Result<JsUnknown> {
|
||||
self.value.into_unknown()
|
||||
pub fn into_unknown(self) -> JsUnknown {
|
||||
JsUnknown::from_raw_unchecked(self.value.0.env, self.value.0.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use super::Value;
|
||||
|
@ -38,10 +37,10 @@ impl JsFunction {
|
|||
Status::Unknown,
|
||||
"Get raw this failed".to_owned(),
|
||||
))?;
|
||||
let mut raw_args = unsafe { mem::MaybeUninit::<[sys::napi_value; 8]>::uninit().assume_init() };
|
||||
for (i, arg) in args.into_iter().enumerate() {
|
||||
raw_args[i] = arg.0.value;
|
||||
}
|
||||
let raw_args = args
|
||||
.iter()
|
||||
.map(|arg| arg.0.value)
|
||||
.collect::<Vec<sys::napi_value>>();
|
||||
let mut return_value = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
sys::napi_call_function(
|
||||
|
@ -49,7 +48,7 @@ impl JsFunction {
|
|||
raw_this,
|
||||
self.0.value,
|
||||
args.len() as u64,
|
||||
&raw_args[0],
|
||||
raw_args.as_ptr(),
|
||||
&mut return_value,
|
||||
)
|
||||
})?;
|
||||
|
|
58
napi/src/js_values/global.rs
Normal file
58
napi/src/js_values/global.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use super::*;
|
||||
use crate::Env;
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct JsGlobal(pub(crate) Value);
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct JsTimeout(pub(crate) Value);
|
||||
|
||||
impl JsGlobal {
|
||||
pub fn set_interval(&self, handler: JsFunction, interval: f64) -> Result<JsTimeout> {
|
||||
let func: JsFunction = self.get_named_property("setInterval")?;
|
||||
func
|
||||
.call(
|
||||
None,
|
||||
&[
|
||||
handler.into_unknown(),
|
||||
Env::from_raw(self.0.env)
|
||||
.create_double(interval)?
|
||||
.into_unknown(),
|
||||
],
|
||||
)
|
||||
.and_then(|ret| ret.try_into())
|
||||
}
|
||||
|
||||
pub fn clear_interval(&self, timer: JsTimeout) -> Result<JsUndefined> {
|
||||
let func: JsFunction = self.get_named_property("clearInterval")?;
|
||||
func
|
||||
.call(None, &[timer.into_unknown()])
|
||||
.and_then(|ret| ret.try_into())
|
||||
}
|
||||
|
||||
pub fn set_timeout(&self, handler: JsFunction, interval: f64) -> Result<JsTimeout> {
|
||||
let func: JsFunction = self.get_named_property("setTimeout")?;
|
||||
func
|
||||
.call(
|
||||
None,
|
||||
&[
|
||||
handler.into_unknown(),
|
||||
Env::from_raw(self.0.env)
|
||||
.create_double(interval)?
|
||||
.into_unknown(),
|
||||
],
|
||||
)
|
||||
.and_then(|ret| ret.try_into())
|
||||
}
|
||||
|
||||
pub fn clear_timeout(&self, timer: JsTimeout) -> Result<JsUndefined> {
|
||||
let func: JsFunction = self.get_named_property("clearTimeout")?;
|
||||
func
|
||||
.call(None, &[timer.into_unknown()])
|
||||
.and_then(|ret| ret.try_into())
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
use std::convert::{From, TryFrom};
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
use crate::error::check_status;
|
||||
|
@ -17,6 +18,7 @@ mod buffer;
|
|||
mod either;
|
||||
mod escapable_handle_scope;
|
||||
mod function;
|
||||
mod global;
|
||||
mod number;
|
||||
mod object;
|
||||
mod object_property;
|
||||
|
@ -37,6 +39,7 @@ pub(crate) use de::De;
|
|||
pub use either::Either;
|
||||
pub use escapable_handle_scope::EscapableHandleScope;
|
||||
pub use function::JsFunction;
|
||||
pub use global::*;
|
||||
pub use number::JsNumber;
|
||||
pub use object::JsObject;
|
||||
pub use object_property::Property;
|
||||
|
@ -120,8 +123,8 @@ macro_rules! impl_js_value_methods {
|
|||
($js_value:ident) => {
|
||||
impl $js_value {
|
||||
#[inline]
|
||||
pub fn into_unknown(self) -> Result<JsUnknown> {
|
||||
JsUnknown::from_raw(self.0.env, self.0.value)
|
||||
pub fn into_unknown(self) -> JsUnknown {
|
||||
JsUnknown::from_raw_unchecked(self.0.env, self.0.value)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -219,6 +222,206 @@ macro_rules! impl_js_value_methods {
|
|||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_object_methods {
|
||||
($js_value:ident) => {
|
||||
impl $js_value {
|
||||
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())
|
||||
})
|
||||
}
|
||||
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(), &mut raw_value)
|
||||
})?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
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())
|
||||
})
|
||||
}
|
||||
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 {
|
||||
sys::napi_get_named_property(self.0.env, self.0.value, key.as_ptr(), &mut raw_value)
|
||||
})?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
pub fn has_named_property<S>(&self, name: S) -> Result<bool>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let mut result = false;
|
||||
let key = CString::new(name.as_ref())?;
|
||||
check_status(unsafe {
|
||||
sys::napi_has_named_property(self.0.env, self.0.value, key.as_ptr(), &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
pub fn delete_property<S>(&mut self, name: S) -> Result<bool>
|
||||
where
|
||||
S: NapiValue,
|
||||
{
|
||||
let mut result = false;
|
||||
check_status(unsafe {
|
||||
sys::napi_delete_property(self.0.env, self.0.value, name.raw(), &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
pub fn delete_named_property(&mut self, name: &str) -> Result<bool> {
|
||||
let mut result = false;
|
||||
let key_str = CString::new(name)?;
|
||||
let mut js_key = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
sys::napi_create_string_utf8(self.0.env, key_str.as_ptr(), name.len() as _, &mut js_key)
|
||||
})?;
|
||||
check_status(unsafe {
|
||||
sys::napi_delete_property(self.0.env, self.0.value, js_key, &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(), &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(), &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
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 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 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()) })
|
||||
}
|
||||
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(&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)
|
||||
})?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
pub fn define_properties(&mut self, properties: &[Property]) -> Result<()> {
|
||||
check_status(unsafe {
|
||||
sys::napi_define_properties(
|
||||
self.0.env,
|
||||
self.0.value,
|
||||
properties.len() as _,
|
||||
properties
|
||||
.iter()
|
||||
.map(|property| property.raw())
|
||||
.collect::<Vec<sys::napi_property_descriptor>>()
|
||||
.as_ptr(),
|
||||
)
|
||||
})
|
||||
}
|
||||
pub fn get_array_length(&self) -> Result<u32> {
|
||||
if self.is_array()? != true {
|
||||
return Err(Error::new(
|
||||
Status::ArrayExpected,
|
||||
"Object is not array".to_owned(),
|
||||
));
|
||||
}
|
||||
self.get_array_length_unchecked()
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_array_length_unchecked(&self) -> Result<u32> {
|
||||
let mut length: u32 = 0;
|
||||
check_status(unsafe { sys::napi_get_array_length(self.0.env, self.raw(), &mut length) })?;
|
||||
Ok(length)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub trait NapiValue: Sized {
|
||||
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self>;
|
||||
|
||||
|
@ -236,9 +439,16 @@ impl_js_value_methods!(JsBuffer);
|
|||
impl_js_value_methods!(JsNumber);
|
||||
impl_js_value_methods!(JsString);
|
||||
impl_js_value_methods!(JsObject);
|
||||
impl_js_value_methods!(JsGlobal);
|
||||
impl_js_value_methods!(JsFunction);
|
||||
impl_js_value_methods!(JsExternal);
|
||||
impl_js_value_methods!(JsSymbol);
|
||||
impl_js_value_methods!(JsTimeout);
|
||||
|
||||
impl_object_methods!(JsObject);
|
||||
impl_object_methods!(JsBuffer);
|
||||
impl_object_methods!(JsArrayBuffer);
|
||||
impl_object_methods!(JsGlobal);
|
||||
|
||||
use ValueType::*;
|
||||
|
||||
|
@ -250,6 +460,8 @@ impl_napi_value_trait!(JsArrayBuffer, Object);
|
|||
impl_napi_value_trait!(JsNumber, Number);
|
||||
impl_napi_value_trait!(JsString, String);
|
||||
impl_napi_value_trait!(JsObject, Object);
|
||||
impl_napi_value_trait!(JsGlobal, Object);
|
||||
impl_napi_value_trait!(JsTimeout, Object);
|
||||
impl_napi_value_trait!(JsFunction, Function);
|
||||
impl_napi_value_trait!(JsExternal, External);
|
||||
impl_napi_value_trait!(JsSymbol, Symbol);
|
||||
|
|
|
@ -1,220 +1,5 @@
|
|||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
use super::Value;
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, Error, JsString, NapiValue, Property, Result, Status};
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct JsObject(pub(crate) Value);
|
||||
|
||||
impl JsObject {
|
||||
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())
|
||||
})
|
||||
}
|
||||
|
||||
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(), &mut raw_value)
|
||||
})?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
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())
|
||||
})
|
||||
}
|
||||
|
||||
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 {
|
||||
sys::napi_get_named_property(self.0.env, self.0.value, key.as_ptr(), &mut raw_value)
|
||||
})?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
pub fn has_named_property<S>(&self, name: S) -> Result<bool>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let mut result = false;
|
||||
let key = CString::new(name.as_ref())?;
|
||||
check_status(unsafe {
|
||||
sys::napi_has_named_property(self.0.env, self.0.value, key.as_ptr(), &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn delete_property<S>(&mut self, name: S) -> Result<bool>
|
||||
where
|
||||
S: NapiValue,
|
||||
{
|
||||
let mut result = false;
|
||||
check_status(unsafe {
|
||||
sys::napi_delete_property(self.0.env, self.0.value, name.raw(), &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn delete_named_property(&mut self, name: &str) -> Result<bool> {
|
||||
let mut result = false;
|
||||
let key_str = CString::new(name)?;
|
||||
let mut js_key = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
sys::napi_create_string_utf8(self.0.env, key_str.as_ptr(), name.len() as _, &mut js_key)
|
||||
})?;
|
||||
check_status(unsafe {
|
||||
sys::napi_delete_property(self.0.env, self.0.value, js_key, &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(), &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(), &mut result)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
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 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 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()) })
|
||||
}
|
||||
|
||||
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(&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)
|
||||
})?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
pub fn define_properties(&mut self, properties: &[Property]) -> Result<()> {
|
||||
check_status(unsafe {
|
||||
sys::napi_define_properties(
|
||||
self.0.env,
|
||||
self.0.value,
|
||||
properties.len() as _,
|
||||
properties
|
||||
.iter()
|
||||
.map(|property| property.raw())
|
||||
.collect::<Vec<sys::napi_property_descriptor>>()
|
||||
.as_ptr(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_array_length(&self) -> Result<u32> {
|
||||
if self.is_array()? != true {
|
||||
return Err(Error::new(
|
||||
Status::ArrayExpected,
|
||||
"Object is not array".to_owned(),
|
||||
));
|
||||
}
|
||||
self.get_array_length_unchecked()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_array_length_unchecked(&self) -> Result<u32> {
|
||||
let mut length: u32 = 0;
|
||||
check_status(unsafe { sys::napi_get_array_length(self.0.env, self.raw(), &mut length) })?;
|
||||
Ok(length)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
"@types/inquirer": "^7.3.1",
|
||||
"@types/lodash": "^4.14.161",
|
||||
"@types/node": "^14.11.2",
|
||||
"@types/sinon": "^9.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "^4.3.0",
|
||||
"@typescript-eslint/parser": "^4.3.0",
|
||||
"ava": "^3.13.0",
|
||||
|
@ -91,6 +92,7 @@
|
|||
"npm-run-all": "^4.1.5",
|
||||
"nyc": "^15.1.0",
|
||||
"prettier": "^2.1.2",
|
||||
"sinon": "^9.1.0",
|
||||
"source-map-support": "^0.5.19",
|
||||
"ts-node": "^9.0.0",
|
||||
"typescript": "^4.0.3"
|
||||
|
|
|
@ -5,6 +5,5 @@ const bindings = require('../index.node')
|
|||
test('should get napi version', (t) => {
|
||||
const napiVersion = bindings.getNapiVersion()
|
||||
t.true(typeof napiVersion === 'number')
|
||||
// @ts-expect-error
|
||||
t.is(`${napiVersion}`, process.versions.napi)
|
||||
})
|
||||
|
|
27
test_module/__test__/global.spec.ts
Normal file
27
test_module/__test__/global.spec.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import test from 'ava'
|
||||
import Sinon from 'sinon'
|
||||
|
||||
const bindings = require('../index.node')
|
||||
|
||||
function wait(delay: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, delay))
|
||||
}
|
||||
|
||||
const delay = 100
|
||||
|
||||
test('should setTimeout', async (t) => {
|
||||
const handler = Sinon.spy()
|
||||
bindings.setTimeout(handler, delay)
|
||||
t.is(handler.callCount, 0)
|
||||
await wait(delay + 10)
|
||||
t.is(handler.callCount, 1)
|
||||
})
|
||||
|
||||
test('should clearTimeout', async (t) => {
|
||||
const handler = Sinon.spy()
|
||||
const timer = setTimeout(() => handler(), delay)
|
||||
t.is(handler.callCount, 0)
|
||||
bindings.clearTimeout(timer)
|
||||
await wait(delay + 10)
|
||||
t.is(handler.callCount, 0)
|
||||
})
|
|
@ -3,8 +3,8 @@ use napi::{CallContext, JsFunction, JsNull, JsObject, Module, Result};
|
|||
#[js_function(1)]
|
||||
pub fn call_function(ctx: CallContext) -> Result<JsNull> {
|
||||
let js_func = ctx.get::<JsFunction>(0)?;
|
||||
let js_string_hello = ctx.env.create_string("hello".as_ref())?.into_unknown()?;
|
||||
let js_string_world = ctx.env.create_string("world".as_ref())?.into_unknown()?;
|
||||
let js_string_hello = ctx.env.create_string("hello".as_ref())?.into_unknown();
|
||||
let js_string_world = ctx.env.create_string("world".as_ref())?.into_unknown();
|
||||
|
||||
js_func.call(None, &[js_string_hello, js_string_world])?;
|
||||
|
||||
|
|
25
test_module/src/global.rs
Normal file
25
test_module/src/global.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use napi::{CallContext, JsFunction, JsNumber, JsTimeout, JsUndefined, Module, Result};
|
||||
|
||||
#[js_function(2)]
|
||||
pub fn set_timeout(ctx: CallContext) -> Result<JsTimeout> {
|
||||
let handler: JsFunction = ctx.get(0)?;
|
||||
let timeout: JsNumber = ctx.get(1)?;
|
||||
ctx
|
||||
.env
|
||||
.get_global()?
|
||||
.set_timeout(handler, timeout.try_into()?)
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn clear_timeout(ctx: CallContext) -> Result<JsUndefined> {
|
||||
let timer: JsTimeout = ctx.get(0)?;
|
||||
ctx.env.get_global()?.clear_timeout(timer)
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
module.create_named_method("setTimeout", set_timeout)?;
|
||||
module.create_named_method("clearTimeout", clear_timeout)?;
|
||||
Ok(())
|
||||
}
|
|
@ -26,6 +26,7 @@ mod env;
|
|||
mod error;
|
||||
mod external;
|
||||
mod function;
|
||||
mod global;
|
||||
mod napi_version;
|
||||
mod object;
|
||||
mod serde;
|
||||
|
@ -52,6 +53,7 @@ fn init(module: &mut Module) -> Result<()> {
|
|||
class::register_js(module)?;
|
||||
env::register_js(module)?;
|
||||
object::register_js(module)?;
|
||||
global::register_js(module)?;
|
||||
#[cfg(napi4)]
|
||||
napi4::register_js(module)?;
|
||||
#[cfg(napi4)]
|
||||
|
|
|
@ -16,7 +16,7 @@ impl ToJs for HandleNumber {
|
|||
fn resolve(&self, env: &mut Env, output: Self::Output) -> Result<Vec<JsUnknown>> {
|
||||
let mut items: Vec<JsUnknown> = vec![];
|
||||
for item in output.iter() {
|
||||
let value = env.create_uint32((*item) as u32)?.into_unknown()?;
|
||||
let value = env.create_uint32((*item) as u32)?.into_unknown();
|
||||
items.push(value);
|
||||
}
|
||||
Ok(items)
|
||||
|
@ -75,9 +75,7 @@ impl ToJs for HandleBuffer {
|
|||
type Output = Vec<u8>;
|
||||
|
||||
fn resolve(&self, env: &mut Env, output: Self::Output) -> Result<Vec<JsUnknown>> {
|
||||
let value = env
|
||||
.create_buffer_with_data(output.to_vec())?
|
||||
.into_unknown()?;
|
||||
let value = env.create_buffer_with_data(output.to_vec())?.into_unknown();
|
||||
Ok(vec![value])
|
||||
}
|
||||
}
|
||||
|
|
96
yarn.lock
96
yarn.lock
|
@ -423,6 +423,42 @@
|
|||
resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
|
||||
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
|
||||
|
||||
"@sinonjs/commons@^1", "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.7.2":
|
||||
version "1.8.1"
|
||||
resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217"
|
||||
integrity sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==
|
||||
dependencies:
|
||||
type-detect "4.0.8"
|
||||
|
||||
"@sinonjs/fake-timers@^6.0.0", "@sinonjs/fake-timers@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40"
|
||||
integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^1.7.0"
|
||||
|
||||
"@sinonjs/formatio@^5.0.1":
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz#f13e713cb3313b1ab965901b01b0828ea6b77089"
|
||||
integrity sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^1"
|
||||
"@sinonjs/samsam" "^5.0.2"
|
||||
|
||||
"@sinonjs/samsam@^5.0.2", "@sinonjs/samsam@^5.1.0":
|
||||
version "5.1.0"
|
||||
resolved "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.1.0.tgz#3afe719232b541bb6cf3411a4c399a188de21ec0"
|
||||
integrity sha512-42nyaQOVunX5Pm6GRJobmzbS7iLI+fhERITnETXzzwDZh+TtDr/Au3yAvXVjFmZ4wEUaE4Y3NFZfKv0bV0cbtg==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^1.6.0"
|
||||
lodash.get "^4.4.2"
|
||||
type-detect "^4.0.8"
|
||||
|
||||
"@sinonjs/text-encoding@^0.7.1":
|
||||
version "0.7.1"
|
||||
resolved "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
|
||||
integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==
|
||||
|
||||
"@swc-node/core@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core/-/core-1.0.0.tgz#d719abe9d5aa49bb169153d1f3b8ef5364f6f30d"
|
||||
|
@ -529,6 +565,18 @@
|
|||
resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
||||
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
|
||||
|
||||
"@types/sinon@^9.0.7":
|
||||
version "9.0.7"
|
||||
resolved "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.7.tgz#c277e19cf9eb0c71106e785650f1e5c299262302"
|
||||
integrity sha512-uyFiy2gp4P/FK9pmU3WIbT5ZzH54hCswwRkQFhxX7xl8jzhW3g+xOkVqk5YP4cIO//Few8UDAX0MtzFpqBEqwA==
|
||||
dependencies:
|
||||
"@types/sinonjs__fake-timers" "*"
|
||||
|
||||
"@types/sinonjs__fake-timers@*":
|
||||
version "6.0.2"
|
||||
resolved "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz#3a84cf5ec3249439015e14049bd3161419bf9eae"
|
||||
integrity sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==
|
||||
|
||||
"@types/through@*":
|
||||
version "0.0.30"
|
||||
resolved "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895"
|
||||
|
@ -1349,7 +1397,7 @@ deprecation@^2.0.0, deprecation@^2.3.1:
|
|||
resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
|
||||
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
|
||||
|
||||
diff@^4.0.1:
|
||||
diff@^4.0.1, diff@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||
|
@ -2304,6 +2352,11 @@ is-yarn-global@^0.3.0:
|
|||
resolved "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232"
|
||||
integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==
|
||||
|
||||
isarray@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
|
||||
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
|
||||
|
||||
isarray@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
|
@ -2458,6 +2511,11 @@ jsonparse@^1.3.1:
|
|||
resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
|
||||
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
|
||||
|
||||
just-extend@^4.0.2:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz#158f1fdb01f128c411dc8b286a7b4837b3545282"
|
||||
integrity sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==
|
||||
|
||||
keyv@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
|
||||
|
@ -2775,6 +2833,17 @@ nice-try@^1.0.4:
|
|||
resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
nise@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz#d73dea3e5731e6561992b8f570be9e363c4512dd"
|
||||
integrity sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^1.7.0"
|
||||
"@sinonjs/fake-timers" "^6.0.0"
|
||||
"@sinonjs/text-encoding" "^0.7.1"
|
||||
just-extend "^4.0.2"
|
||||
path-to-regexp "^1.7.0"
|
||||
|
||||
node-fetch@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
|
@ -3144,6 +3213,13 @@ path-parse@^1.0.6:
|
|||
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
|
||||
path-to-regexp@^1.7.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
|
||||
integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
|
||||
dependencies:
|
||||
isarray "0.0.1"
|
||||
|
||||
path-type@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
|
||||
|
@ -3580,6 +3656,19 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
|||
resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||
|
||||
sinon@^9.1.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.npmjs.org/sinon/-/sinon-9.1.0.tgz#4afc90707c8e360fe051398eed2d3b197980ffc3"
|
||||
integrity sha512-9zQShgaeylYH6qtsnNXlTvv0FGTTckuDfHBi+qhgj5PvW2r2WslHZpgc3uy3e/ZAoPkqaOASPi+juU6EdYRYxA==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^1.7.2"
|
||||
"@sinonjs/fake-timers" "^6.0.1"
|
||||
"@sinonjs/formatio" "^5.0.1"
|
||||
"@sinonjs/samsam" "^5.1.0"
|
||||
diff "^4.0.2"
|
||||
nise "^4.0.4"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
slash@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||
|
@ -3950,6 +4039,11 @@ type-check@^0.4.0, type-check@~0.4.0:
|
|||
dependencies:
|
||||
prelude-ls "^1.2.1"
|
||||
|
||||
type-detect@4.0.8, type-detect@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
|
||||
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
|
||||
|
||||
type-fest@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1"
|
||||
|
|
Loading…
Reference in a new issue