2020-04-17 12:54:17 +09:00
|
|
|
extern crate futures;
|
2020-04-03 01:09:44 +09:00
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
use core::fmt::Debug;
|
|
|
|
use futures::prelude::*;
|
2018-04-28 17:26:38 +09:00
|
|
|
use std::any::TypeId;
|
2020-04-26 19:46:56 +09:00
|
|
|
use std::convert::{TryFrom, TryInto};
|
2018-04-28 17:26:38 +09:00
|
|
|
use std::ffi::CString;
|
|
|
|
use std::marker::PhantomData;
|
|
|
|
use std::mem;
|
2019-05-16 01:41:22 +09:00
|
|
|
use std::ops::{Deref, DerefMut};
|
2018-04-28 17:26:38 +09:00
|
|
|
use std::os::raw::{c_char, c_void};
|
|
|
|
use std::ptr;
|
2019-05-16 01:41:22 +09:00
|
|
|
use std::slice;
|
2020-05-01 02:26:56 +09:00
|
|
|
use std::str;
|
2018-04-28 17:26:38 +09:00
|
|
|
use std::string::String as RustString;
|
|
|
|
|
2020-04-26 19:46:56 +09:00
|
|
|
mod call_context;
|
2018-04-28 17:26:38 +09:00
|
|
|
mod executor;
|
2020-05-06 00:13:23 +09:00
|
|
|
mod promise;
|
2018-04-28 17:26:38 +09:00
|
|
|
pub mod sys;
|
2020-05-06 00:13:23 +09:00
|
|
|
mod version;
|
2018-04-28 17:26:38 +09:00
|
|
|
|
2020-04-21 01:20:35 +09:00
|
|
|
pub use call_context::CallContext;
|
2020-01-16 23:10:06 +09:00
|
|
|
pub use sys::{napi_valuetype, Status};
|
2020-05-06 00:13:23 +09:00
|
|
|
pub use version::NodeVersion;
|
2018-04-28 17:26:38 +09:00
|
|
|
|
|
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
|
|
pub type Callback = extern "C" fn(sys::napi_env, sys::napi_callback_info) -> sys::napi_value;
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
#[derive(Debug, Clone)]
|
2018-04-28 17:26:38 +09:00
|
|
|
pub struct Error {
|
2020-05-06 00:13:23 +09:00
|
|
|
pub status: Status,
|
|
|
|
pub reason: Option<String>,
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct Env(sys::napi_env);
|
|
|
|
|
|
|
|
// Value types
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct Any;
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct Undefined;
|
|
|
|
|
2020-04-03 01:09:44 +09:00
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct Null;
|
|
|
|
|
2018-04-28 17:26:38 +09:00
|
|
|
#[derive(Clone, Copy, Debug)]
|
2019-05-23 20:28:51 +09:00
|
|
|
pub struct Boolean {
|
|
|
|
value: bool,
|
|
|
|
}
|
2018-04-28 17:26:38 +09:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
2020-04-03 01:09:44 +09:00
|
|
|
pub enum Number {
|
|
|
|
Int(i64),
|
2020-04-26 19:46:56 +09:00
|
|
|
Int32(i32),
|
2020-04-20 01:43:48 +09:00
|
|
|
U32(u32),
|
2020-04-03 01:09:44 +09:00
|
|
|
Double(f64),
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
2018-04-28 17:26:38 +09:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
2020-05-01 02:26:56 +09:00
|
|
|
pub struct JsString;
|
2018-04-28 17:26:38 +09:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct Object;
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct Function;
|
|
|
|
|
2019-05-16 01:41:22 +09:00
|
|
|
#[derive(Clone, Copy, Debug)]
|
2019-05-23 20:28:51 +09:00
|
|
|
pub struct Buffer {
|
|
|
|
data: *const u8,
|
2020-02-18 22:09:17 +09:00
|
|
|
size: u64,
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
2019-05-16 01:41:22 +09:00
|
|
|
|
2020-04-09 00:58:50 +09:00
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct ArrayBuffer {
|
|
|
|
data: *const u8,
|
|
|
|
size: u64,
|
|
|
|
}
|
|
|
|
|
2018-04-28 17:26:38 +09:00
|
|
|
#[derive(Clone, Copy, Debug)]
|
2020-05-06 00:13:23 +09:00
|
|
|
pub struct Value<T> {
|
|
|
|
env: sys::napi_env,
|
2018-04-28 17:26:38 +09:00
|
|
|
raw_value: sys::napi_value,
|
2019-05-23 20:28:51 +09:00
|
|
|
value: T,
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Ref<T> {
|
|
|
|
raw_env: sys::napi_env,
|
|
|
|
raw_ref: sys::napi_ref,
|
|
|
|
_marker: PhantomData<T>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct Property {
|
|
|
|
name: RustString,
|
|
|
|
raw_descriptor: sys::napi_property_descriptor,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
struct TaggedObject<T> {
|
|
|
|
type_id: TypeId,
|
|
|
|
object: Option<T>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! register_module {
|
|
|
|
($module_name:ident, $init:ident) => {
|
|
|
|
#[no_mangle]
|
|
|
|
#[cfg_attr(target_os = "linux", link_section = ".ctors")]
|
|
|
|
#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
|
|
|
|
#[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
|
|
|
|
pub static __REGISTER_MODULE: extern "C" fn() = {
|
|
|
|
use std::io::Write;
|
|
|
|
use std::os::raw::c_char;
|
|
|
|
use std::ptr;
|
|
|
|
use $crate::sys;
|
|
|
|
|
|
|
|
extern "C" fn register_module() {
|
|
|
|
static mut MODULE_DESCRIPTOR: Option<sys::napi_module> = None;
|
|
|
|
unsafe {
|
|
|
|
MODULE_DESCRIPTOR = Some(sys::napi_module {
|
|
|
|
nm_version: 1,
|
|
|
|
nm_flags: 0,
|
|
|
|
nm_filename: concat!(file!(), "\0").as_ptr() as *const c_char,
|
|
|
|
nm_register_func: Some(init_module),
|
|
|
|
nm_modname: concat!(stringify!($module_name), "\0").as_ptr() as *const c_char,
|
|
|
|
nm_priv: 0 as *mut _,
|
|
|
|
reserved: [0 as *mut _; 4],
|
|
|
|
});
|
|
|
|
|
|
|
|
sys::napi_module_register(MODULE_DESCRIPTOR.as_mut().unwrap() as *mut sys::napi_module);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" fn init_module(
|
|
|
|
raw_env: sys::napi_env,
|
|
|
|
raw_exports: sys::napi_value,
|
|
|
|
) -> sys::napi_value {
|
|
|
|
let env = Env::from_raw(raw_env);
|
2020-05-06 00:13:23 +09:00
|
|
|
let mut exports: Value<Object> = Value::from_raw(raw_env, raw_exports).unwrap();
|
2018-04-28 17:26:38 +09:00
|
|
|
|
|
|
|
let result = $init(&env, &mut exports);
|
|
|
|
|
|
|
|
match result {
|
2020-05-09 16:14:44 +09:00
|
|
|
Ok(_) => exports.into_raw(),
|
2018-04-28 17:26:38 +09:00
|
|
|
Err(e) => {
|
2020-05-09 16:14:44 +09:00
|
|
|
unsafe {
|
|
|
|
sys::napi_throw_error(
|
|
|
|
raw_env,
|
|
|
|
ptr::null(),
|
|
|
|
format!("Error initializing module: {:?}", e).as_ptr() as *const _,
|
|
|
|
)
|
|
|
|
};
|
2018-04-28 17:26:38 +09:00
|
|
|
ptr::null_mut()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
register_module
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error {
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn from_status(status: Status) -> Self {
|
|
|
|
Error {
|
|
|
|
status: status,
|
|
|
|
reason: None,
|
|
|
|
}
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<std::ffi::NulError> for Error {
|
2020-05-06 00:13:23 +09:00
|
|
|
fn from(error: std::ffi::NulError) -> Self {
|
2018-04-28 17:26:38 +09:00
|
|
|
Error {
|
2020-05-01 02:26:56 +09:00
|
|
|
status: Status::StringExpected,
|
2020-05-06 00:13:23 +09:00
|
|
|
reason: Some(format!("{:?}", error)),
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Env {
|
|
|
|
pub fn from_raw(env: sys::napi_env) -> Self {
|
|
|
|
Env(env)
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn get_undefined(&self) -> Result<Value<Undefined>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let status = unsafe { sys::napi_get_undefined(self.0, &mut raw_value) };
|
2020-04-03 01:09:44 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(self, raw_value, Undefined))
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn get_null(&self) -> Result<Value<Null>> {
|
2020-04-03 01:09:44 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let status = unsafe { sys::napi_get_null(self.0, &mut raw_value) };
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(self, raw_value, Null))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
pub fn get_boolean(&self, value: bool) -> Result<Value<Boolean>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let status = unsafe { sys::napi_get_boolean(self.0, value, &mut raw_value) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(self, raw_value, Boolean { value }))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn create_int32(&self, int: i32) -> Result<Value<Number>> {
|
2020-04-26 19:46:56 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let status =
|
|
|
|
unsafe { sys::napi_create_int32(self.0, int, (&mut raw_value) as *mut sys::napi_value) };
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(self, raw_value, Number::Int32(int)))
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn create_int64(&self, int: i64) -> Result<Value<Number>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let status =
|
|
|
|
unsafe { sys::napi_create_int64(self.0, int, (&mut raw_value) as *mut sys::napi_value) };
|
2020-04-03 01:09:44 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(self, raw_value, Number::Int(int)))
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn create_uint32(&self, number: u32) -> Result<Value<Number>> {
|
2020-04-20 01:43:48 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
2020-05-09 16:14:44 +09:00
|
|
|
let status = unsafe { sys::napi_create_uint32(self.0, number, &mut raw_value) };
|
2020-04-20 01:43:48 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(self, raw_value, Number::U32(number)))
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn create_double(&self, double: f64) -> Result<Value<Number>> {
|
2020-04-03 01:09:44 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let status =
|
|
|
|
unsafe { sys::napi_create_double(self.0, double, (&mut raw_value) as *mut sys::napi_value) };
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(
|
|
|
|
self,
|
|
|
|
raw_value,
|
|
|
|
Number::Double(double),
|
|
|
|
))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn create_string<'a, 'b>(&'a self, s: &'b str) -> Result<Value<JsString>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let status = unsafe {
|
2020-02-18 22:09:17 +09:00
|
|
|
sys::napi_create_string_utf8(
|
|
|
|
self.0,
|
|
|
|
s.as_ptr() as *const c_char,
|
|
|
|
s.len() as u64,
|
|
|
|
&mut raw_value,
|
|
|
|
)
|
2018-04-28 17:26:38 +09:00
|
|
|
};
|
2020-04-03 01:09:44 +09:00
|
|
|
check_status(status)?;
|
2020-05-01 02:26:56 +09:00
|
|
|
Ok(Value::from_raw_value(self, raw_value, JsString))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-05-01 02:26:56 +09:00
|
|
|
pub fn create_string_utf16(&self, chars: &[u16]) -> Result<Value<JsString>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
2020-02-18 22:09:17 +09:00
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_create_string_utf16(self.0, chars.as_ptr(), chars.len() as u64, &mut raw_value)
|
|
|
|
};
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
2020-05-01 02:26:56 +09:00
|
|
|
Ok(Value::from_raw_value(self, raw_value, JsString))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn create_object(&self) -> Result<Value<Object>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let status = unsafe { sys::napi_create_object(self.0, &mut raw_value) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(self, raw_value, Object))
|
2020-04-03 01:09:44 +09:00
|
|
|
}
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
pub fn create_array_with_length(&self, length: usize) -> Result<Value<Object>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
2020-02-18 22:09:17 +09:00
|
|
|
let status =
|
|
|
|
unsafe { sys::napi_create_array_with_length(self.0, length as u64, &mut raw_value) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(self, raw_value, Object))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
pub fn create_buffer(&self, length: u64) -> Result<Value<Buffer>> {
|
2019-05-16 01:41:22 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
2019-05-23 20:28:51 +09:00
|
|
|
let mut data = ptr::null_mut();
|
|
|
|
let status = unsafe { sys::napi_create_buffer(self.0, length, &mut data, &mut raw_value) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(
|
2019-05-23 20:28:51 +09:00
|
|
|
self,
|
|
|
|
raw_value,
|
|
|
|
Buffer {
|
|
|
|
data: data as *const u8,
|
|
|
|
size: length,
|
|
|
|
},
|
2020-04-17 12:54:17 +09:00
|
|
|
))
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
pub fn create_buffer_with_data(&self, data: Vec<u8>) -> Result<Value<Buffer>> {
|
2020-02-21 01:45:30 +09:00
|
|
|
let length = data.len() as u64;
|
2019-05-23 20:28:51 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
2020-02-21 01:45:30 +09:00
|
|
|
let data_ptr = data.as_ptr();
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_create_external_buffer(
|
|
|
|
self.0,
|
|
|
|
length,
|
|
|
|
data_ptr as *mut c_void,
|
|
|
|
Some(drop_buffer),
|
|
|
|
Box::into_raw(Box::from(length)) as *mut c_void,
|
|
|
|
&mut raw_value,
|
|
|
|
)
|
|
|
|
};
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
2020-02-21 01:45:30 +09:00
|
|
|
let mut changed = 0;
|
|
|
|
let ajust_external_memory_status =
|
|
|
|
unsafe { sys::napi_adjust_external_memory(self.0, length as i64, &mut changed) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(ajust_external_memory_status)?;
|
2020-02-21 01:45:30 +09:00
|
|
|
mem::forget(data);
|
2020-04-17 12:54:17 +09:00
|
|
|
Ok(Value::from_raw_value(
|
2019-05-23 20:28:51 +09:00
|
|
|
self,
|
|
|
|
raw_value,
|
|
|
|
Buffer {
|
|
|
|
data: data_ptr,
|
|
|
|
size: length,
|
|
|
|
},
|
2020-04-17 12:54:17 +09:00
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn create_arraybuffer(&self, length: u64) -> Result<Value<ArrayBuffer>> {
|
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let mut data = ptr::null_mut();
|
|
|
|
let status = unsafe { sys::napi_create_arraybuffer(self.0, length, &mut data, &mut raw_value) };
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(
|
|
|
|
self,
|
|
|
|
raw_value,
|
|
|
|
ArrayBuffer {
|
|
|
|
data: data as *const u8,
|
|
|
|
size: length,
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn create_arraybuffer_with_data(&self, data: Vec<u8>) -> Result<Value<ArrayBuffer>> {
|
|
|
|
let length = data.len() as u64;
|
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let data_ptr = data.as_ptr();
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_create_external_arraybuffer(
|
|
|
|
self.0,
|
|
|
|
data_ptr as *mut c_void,
|
|
|
|
length,
|
|
|
|
Some(drop_buffer),
|
|
|
|
Box::into_raw(Box::from(length)) as *mut c_void,
|
|
|
|
&mut raw_value,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
check_status(status)?;
|
|
|
|
let mut changed = 0;
|
|
|
|
let ajust_external_memory_status =
|
|
|
|
unsafe { sys::napi_adjust_external_memory(self.0, length as i64, &mut changed) };
|
|
|
|
check_status(ajust_external_memory_status)?;
|
|
|
|
mem::forget(data);
|
|
|
|
Ok(Value::from_raw_value(
|
|
|
|
self,
|
|
|
|
raw_value,
|
|
|
|
ArrayBuffer {
|
|
|
|
data: data_ptr,
|
|
|
|
size: length,
|
|
|
|
},
|
|
|
|
))
|
2019-05-16 01:41:22 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn create_function(&self, name: &str, callback: Callback) -> Result<Value<Function>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_result = ptr::null_mut();
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_create_function(
|
|
|
|
self.0,
|
|
|
|
name.as_ptr() as *const c_char,
|
2020-02-18 22:09:17 +09:00
|
|
|
name.len() as u64,
|
2018-04-28 17:26:38 +09:00
|
|
|
Some(callback),
|
|
|
|
callback as *mut c_void,
|
|
|
|
&mut raw_result,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
2018-04-28 17:26:38 +09:00
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
Ok(Value::from_raw_value(self, raw_result, Function))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-05-01 02:26:56 +09:00
|
|
|
pub fn throw_error(&self, msg: &str) -> Result<()> {
|
|
|
|
let status = unsafe { sys::napi_throw_error(self.0, ptr::null(), msg.as_ptr() as *const _) };
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
pub fn create_reference<T>(&self, value: &Value<T>) -> Result<Ref<T>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_ref = ptr::null_mut();
|
|
|
|
unsafe {
|
|
|
|
let status = sys::napi_create_reference(self.0, value.raw_value, 1, &mut raw_ref);
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
2018-04-28 17:26:38 +09:00
|
|
|
};
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
Ok(Ref {
|
2018-04-28 17:26:38 +09:00
|
|
|
raw_env: self.0,
|
|
|
|
raw_ref,
|
|
|
|
_marker: PhantomData,
|
2020-04-17 12:54:17 +09:00
|
|
|
})
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
pub fn get_reference_value<T: ValueType>(&self, reference: &Ref<T>) -> Result<Value<T>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
unsafe {
|
|
|
|
let status = sys::napi_get_reference_value(self.0, reference.raw_ref, &mut raw_value);
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
2018-04-28 17:26:38 +09:00
|
|
|
};
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
Value::from_raw(self.0, raw_value)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn define_class<'a, 'b>(
|
|
|
|
&'a self,
|
|
|
|
name: &'b str,
|
|
|
|
constructor_cb: Callback,
|
|
|
|
properties: Vec<Property>,
|
2020-05-06 00:13:23 +09:00
|
|
|
) -> Result<Value<Function>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_result = ptr::null_mut();
|
|
|
|
let raw_properties = properties
|
|
|
|
.into_iter()
|
|
|
|
.map(|prop| prop.into_raw(self))
|
2020-04-03 01:09:44 +09:00
|
|
|
.collect::<Result<Vec<sys::napi_property_descriptor>>>()?;
|
2018-04-28 17:26:38 +09:00
|
|
|
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_define_class(
|
|
|
|
self.0,
|
|
|
|
name.as_ptr() as *const c_char,
|
2020-02-18 22:09:17 +09:00
|
|
|
name.len() as u64,
|
2018-04-28 17:26:38 +09:00
|
|
|
Some(constructor_cb),
|
|
|
|
ptr::null_mut(),
|
2020-02-18 22:09:17 +09:00
|
|
|
raw_properties.len() as u64,
|
2018-04-28 17:26:38 +09:00
|
|
|
raw_properties.as_ptr(),
|
|
|
|
&mut raw_result,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
|
2020-04-03 01:09:44 +09:00
|
|
|
check_status(status)?;
|
2018-04-28 17:26:38 +09:00
|
|
|
|
2020-04-03 01:09:44 +09:00
|
|
|
Ok(Value::from_raw_value(self, raw_result, Function))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn wrap<T: 'static>(&self, js_object: &mut Value<Object>, native_object: T) -> Result<()> {
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_wrap(
|
|
|
|
self.0,
|
|
|
|
js_object.raw_value,
|
|
|
|
Box::into_raw(Box::new(TaggedObject::new(native_object))) as *mut c_void,
|
|
|
|
Some(raw_finalize::<T>),
|
|
|
|
ptr::null_mut(),
|
|
|
|
ptr::null_mut(),
|
|
|
|
)
|
|
|
|
};
|
|
|
|
|
|
|
|
check_status(status).or(Ok(()))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn unwrap<T: 'static>(&self, js_object: &Value<Object>) -> Result<&mut T> {
|
|
|
|
unsafe {
|
|
|
|
let mut unknown_tagged_object: *mut c_void = ptr::null_mut();
|
|
|
|
let status = sys::napi_unwrap(self.0, js_object.raw_value, &mut unknown_tagged_object);
|
|
|
|
check_status(status)?;
|
|
|
|
|
|
|
|
let type_id: *const TypeId = mem::transmute(unknown_tagged_object);
|
|
|
|
if *type_id == TypeId::of::<T>() {
|
|
|
|
let tagged_object: *mut TaggedObject<T> = mem::transmute(unknown_tagged_object);
|
|
|
|
(*tagged_object).object.as_mut().ok_or(Error {
|
|
|
|
status: Status::InvalidArg,
|
2020-05-06 00:13:23 +09:00
|
|
|
reason: Some("Invalid argument, nothing attach to js_object".to_owned()),
|
2018-04-28 17:26:38 +09:00
|
|
|
})
|
|
|
|
} else {
|
|
|
|
Err(Error {
|
|
|
|
status: Status::InvalidArg,
|
2020-05-06 00:13:23 +09:00
|
|
|
reason: Some(
|
|
|
|
"Invalid argument, T on unrwap is not the type of wrapped object".to_owned(),
|
|
|
|
),
|
2018-04-28 17:26:38 +09:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn drop_wrapped<T: 'static>(&self, js_object: Value<Object>) -> Result<()> {
|
|
|
|
unsafe {
|
|
|
|
let mut unknown_tagged_object: *mut c_void = ptr::null_mut();
|
|
|
|
let status = sys::napi_unwrap(self.0, js_object.raw_value, &mut unknown_tagged_object);
|
|
|
|
check_status(status)?;
|
|
|
|
|
|
|
|
let type_id: *const TypeId = mem::transmute(unknown_tagged_object);
|
|
|
|
if *type_id == TypeId::of::<T>() {
|
|
|
|
let tagged_object: *mut TaggedObject<T> = mem::transmute(unknown_tagged_object);
|
|
|
|
(*tagged_object).object = None;
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(Error {
|
|
|
|
status: Status::InvalidArg,
|
2020-05-06 00:13:23 +09:00
|
|
|
reason: Some(
|
|
|
|
"Invalid argument, T on drop_wrapped is not the type of wrapped object".to_owned(),
|
|
|
|
),
|
2018-04-28 17:26:38 +09:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn create_error(&self, e: Error) -> Result<Value<Object>> {
|
|
|
|
let reason = e.reason.unwrap_or("".to_owned());
|
|
|
|
let reason_string = self.create_string(reason.as_str())?;
|
|
|
|
let mut result = ptr::null_mut();
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_create_error(
|
|
|
|
self.0,
|
|
|
|
ptr::null_mut(),
|
|
|
|
reason_string.into_raw(),
|
|
|
|
&mut result,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value::from_raw_value(self, result, Object))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn perform_async_operation<
|
|
|
|
T: 'static,
|
|
|
|
V: 'static + ValueType,
|
|
|
|
F: 'static + Future<Output = Result<T>>,
|
|
|
|
R: 'static + FnOnce(&mut Env, T) -> Result<Value<V>>,
|
|
|
|
>(
|
|
|
|
&self,
|
|
|
|
deferred: F,
|
|
|
|
resolver: R,
|
|
|
|
) -> Result<Value<Object>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_promise = ptr::null_mut();
|
|
|
|
let mut raw_deferred = ptr::null_mut();
|
|
|
|
|
|
|
|
unsafe {
|
2020-04-03 01:09:44 +09:00
|
|
|
let status = sys::napi_create_promise(self.0, &mut raw_deferred, &mut raw_promise);
|
|
|
|
check_status(status)?;
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
let event_loop = unsafe { sys::uv_default_loop() };
|
|
|
|
let raw_env = self.0;
|
|
|
|
executor::execute(
|
|
|
|
event_loop,
|
|
|
|
promise::resolve(self.0, deferred, resolver, raw_deferred).map(move |v| match v {
|
|
|
|
Ok(value) => value,
|
|
|
|
Err(e) => {
|
|
|
|
let cloned_error = e.clone();
|
|
|
|
unsafe {
|
|
|
|
sys::napi_throw_error(
|
|
|
|
raw_env,
|
|
|
|
ptr::null(),
|
|
|
|
e.reason.unwrap_or(format!("{:?}", e.status)).as_ptr() as *const _,
|
|
|
|
);
|
|
|
|
};
|
|
|
|
eprintln!("{:?}", &cloned_error);
|
|
|
|
panic!(cloned_error);
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
)?;
|
2018-04-28 17:26:38 +09:00
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
Ok(Value::from_raw_value(self, raw_promise, Object))
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn get_node_version(&self) -> Result<NodeVersion> {
|
|
|
|
let mut result = ptr::null();
|
|
|
|
check_status(unsafe { sys::napi_get_node_version(self.0, &mut result) })?;
|
|
|
|
let version = unsafe { *result };
|
|
|
|
version.try_into()
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub trait ValueType: Copy + Debug {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(env: sys::napi_env, raw: sys::napi_value) -> Result<Self>;
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool>;
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ValueType for Any {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(_env: sys::napi_env, _raw: sys::napi_value) -> Result<Self> {
|
|
|
|
Ok(Any)
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(_env: sys::napi_env, _raw: sys::napi_value) -> Result<bool> {
|
|
|
|
Ok(true)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ValueType for Undefined {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(_env: sys::napi_env, _raw: sys::napi_value) -> Result<Self> {
|
|
|
|
Ok(Undefined)
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool> {
|
|
|
|
Ok(get_raw_type(env, raw)? == sys::napi_valuetype::napi_undefined)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-03 01:09:44 +09:00
|
|
|
impl ValueType for Null {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(_env: sys::napi_env, _raw: sys::napi_value) -> Result<Self> {
|
|
|
|
Ok(Null)
|
2020-04-03 01:09:44 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool> {
|
|
|
|
Ok(get_raw_type(env, raw)? == sys::napi_valuetype::napi_null)
|
2020-04-03 01:09:44 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-28 17:26:38 +09:00
|
|
|
impl ValueType for Boolean {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(env: sys::napi_env, raw: sys::napi_value) -> Result<Self> {
|
2019-05-23 20:28:51 +09:00
|
|
|
let mut value = true;
|
|
|
|
let status = unsafe { sys::napi_get_value_bool(env, raw, &mut value) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Boolean { value })
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool> {
|
|
|
|
Ok(get_raw_type(env, raw)? == sys::napi_valuetype::napi_boolean)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ValueType for Number {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(env: sys::napi_env, raw: sys::napi_value) -> Result<Self> {
|
2020-04-03 01:09:44 +09:00
|
|
|
let mut double: f64 = 0.0;
|
|
|
|
let status = unsafe { sys::napi_get_value_double(env, raw, &mut double) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Number::Double(double))
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool> {
|
|
|
|
Ok(get_raw_type(env, raw)? == sys::napi_valuetype::napi_number)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:26:56 +09:00
|
|
|
impl ValueType for JsString {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(_env: sys::napi_env, _raw: sys::napi_value) -> Result<Self> {
|
2020-05-01 02:26:56 +09:00
|
|
|
Ok(JsString {})
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool> {
|
|
|
|
Ok(get_raw_type(env, raw)? == sys::napi_valuetype::napi_string)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ValueType for Object {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(_env: sys::napi_env, _raw: sys::napi_value) -> Result<Self> {
|
|
|
|
Ok(Object {})
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool> {
|
|
|
|
Ok(get_raw_type(env, raw)? == sys::napi_valuetype::napi_object)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-16 01:41:22 +09:00
|
|
|
impl ValueType for Buffer {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(env: sys::napi_env, raw: sys::napi_value) -> Result<Self> {
|
2019-05-23 20:28:51 +09:00
|
|
|
let mut data = ptr::null_mut();
|
2020-02-18 22:09:17 +09:00
|
|
|
let mut size: u64 = 0;
|
2019-05-23 20:28:51 +09:00
|
|
|
let status = unsafe { sys::napi_get_buffer_info(env, raw, &mut data, &mut size) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Buffer {
|
2019-05-23 20:28:51 +09:00
|
|
|
data: data as *const u8,
|
|
|
|
size,
|
2020-04-17 12:54:17 +09:00
|
|
|
})
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool> {
|
2019-05-23 20:28:51 +09:00
|
|
|
let mut result = false;
|
|
|
|
unsafe {
|
|
|
|
let status = sys::napi_is_buffer(env, raw, &mut result);
|
2020-05-06 00:13:23 +09:00
|
|
|
check_status(status)?;
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
2020-05-06 00:13:23 +09:00
|
|
|
Ok(result)
|
2019-05-16 01:41:22 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-09 00:58:50 +09:00
|
|
|
impl ValueType for ArrayBuffer {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(env: sys::napi_env, raw: sys::napi_value) -> Result<Self> {
|
2020-04-09 00:58:50 +09:00
|
|
|
let mut data = ptr::null_mut();
|
|
|
|
let mut size: u64 = 0;
|
|
|
|
let status = unsafe { sys::napi_get_arraybuffer_info(env, raw, &mut data, &mut size) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(ArrayBuffer {
|
2020-04-09 00:58:50 +09:00
|
|
|
data: data as *const u8,
|
|
|
|
size,
|
2020-04-17 12:54:17 +09:00
|
|
|
})
|
2020-04-09 00:58:50 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool> {
|
2020-04-09 00:58:50 +09:00
|
|
|
let mut result = false;
|
|
|
|
unsafe {
|
|
|
|
let status = sys::napi_is_arraybuffer(env, raw, &mut result);
|
2020-05-06 00:13:23 +09:00
|
|
|
check_status(status)?;
|
2020-04-09 00:58:50 +09:00
|
|
|
}
|
2020-05-06 00:13:23 +09:00
|
|
|
Ok(result)
|
2020-04-09 00:58:50 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl Value<Buffer> {
|
2020-02-22 13:34:04 +09:00
|
|
|
#[inline]
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn from_value(env: &Env, value: &Value<Any>) -> Result<Value<Buffer>> {
|
2020-04-17 12:54:17 +09:00
|
|
|
Ok(Value {
|
2020-05-06 00:13:23 +09:00
|
|
|
env: env.0,
|
2020-02-22 13:34:04 +09:00
|
|
|
raw_value: value.raw_value,
|
2020-04-17 12:54:17 +09:00
|
|
|
value: Buffer::from_raw(env.0, value.into_raw())?,
|
|
|
|
})
|
2020-02-22 13:34:04 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-28 17:26:38 +09:00
|
|
|
impl ValueType for Function {
|
2020-04-17 12:54:17 +09:00
|
|
|
fn from_raw(_env: sys::napi_env, _raw: sys::napi_value) -> Result<Self> {
|
|
|
|
Ok(Function {})
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn matches_raw_type(env: sys::napi_env, raw: sys::napi_value) -> Result<bool> {
|
|
|
|
Ok(get_raw_type(env, raw)? == sys::napi_valuetype::napi_function)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl<T: ValueType> Value<T> {
|
|
|
|
pub fn from_raw_value(env: &Env, raw_value: sys::napi_value, value: T) -> Self {
|
2019-05-23 20:28:51 +09:00
|
|
|
Self {
|
2020-05-06 00:13:23 +09:00
|
|
|
env: env.0,
|
2019-05-23 20:28:51 +09:00
|
|
|
raw_value,
|
|
|
|
value,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn from_raw(env: sys::napi_env, raw_value: sys::napi_value) -> Result<Self> {
|
2020-04-17 12:54:17 +09:00
|
|
|
Ok(Self {
|
2018-04-28 17:26:38 +09:00
|
|
|
env,
|
|
|
|
raw_value,
|
2020-05-06 00:13:23 +09:00
|
|
|
value: T::from_raw(env, raw_value)?,
|
2020-04-17 12:54:17 +09:00
|
|
|
})
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn into_raw(self) -> sys::napi_value {
|
|
|
|
self.raw_value
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn coerce_to_number(self) -> Result<Value<Number>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut new_raw_value = ptr::null_mut();
|
|
|
|
let status =
|
2020-05-06 00:13:23 +09:00
|
|
|
unsafe { sys::napi_coerce_to_number(self.env, self.raw_value, &mut new_raw_value) };
|
2018-04-28 17:26:38 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value {
|
|
|
|
env: self.env,
|
|
|
|
raw_value: self.raw_value,
|
2020-05-06 00:13:23 +09:00
|
|
|
value: Number::from_raw(self.env, self.raw_value)?,
|
2018-04-28 17:26:38 +09:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn coerce_to_string(self) -> Result<Value<JsString>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut new_raw_value = ptr::null_mut();
|
|
|
|
let status =
|
2020-05-06 00:13:23 +09:00
|
|
|
unsafe { sys::napi_coerce_to_string(self.env, self.raw_value, &mut new_raw_value) };
|
2018-04-28 17:26:38 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value {
|
|
|
|
env: self.env,
|
|
|
|
raw_value: self.raw_value,
|
2020-05-01 02:26:56 +09:00
|
|
|
value: JsString,
|
2018-04-28 17:26:38 +09:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn coerce_to_object(self) -> Result<Value<Object>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut new_raw_value = ptr::null_mut();
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_coerce_to_object(
|
2020-05-06 00:13:23 +09:00
|
|
|
self.env,
|
2018-04-28 17:26:38 +09:00
|
|
|
self.raw_value,
|
|
|
|
(&mut new_raw_value) as *mut sys::napi_value,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(Value {
|
|
|
|
env: self.env,
|
|
|
|
raw_value: self.raw_value,
|
2019-05-23 20:28:51 +09:00
|
|
|
value: Object,
|
2018-04-28 17:26:38 +09:00
|
|
|
})
|
|
|
|
}
|
2020-04-03 01:09:44 +09:00
|
|
|
|
|
|
|
#[inline]
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn into_any(self) -> Value<Any> {
|
2020-04-03 01:09:44 +09:00
|
|
|
Value {
|
|
|
|
env: self.env,
|
|
|
|
raw_value: self.raw_value,
|
|
|
|
value: Any,
|
|
|
|
}
|
|
|
|
}
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2019-05-23 20:28:51 +09:00
|
|
|
#[inline]
|
2020-05-06 00:13:23 +09:00
|
|
|
fn get_raw_type(env: sys::napi_env, raw_value: sys::napi_value) -> Result<sys::napi_valuetype> {
|
2019-05-23 20:28:51 +09:00
|
|
|
unsafe {
|
2020-02-18 22:09:17 +09:00
|
|
|
let value_type = ptr::null_mut();
|
2020-05-06 00:13:23 +09:00
|
|
|
check_status(sys::napi_typeof(env, raw_value, value_type))?;
|
|
|
|
Ok(*value_type)
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl Value<Boolean> {
|
2020-05-02 00:52:01 +09:00
|
|
|
pub fn get_value(&self) -> bool {
|
|
|
|
self.value.value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl Value<JsString> {
|
2020-04-17 12:54:17 +09:00
|
|
|
pub fn len(&self) -> Result<usize> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut raw_length = ptr::null_mut();
|
|
|
|
unsafe {
|
|
|
|
let status = sys::napi_get_named_property(
|
2020-05-06 00:13:23 +09:00
|
|
|
self.env,
|
2018-04-28 17:26:38 +09:00
|
|
|
self.raw_value,
|
|
|
|
"length\0".as_ptr() as *const c_char,
|
|
|
|
&mut raw_length,
|
|
|
|
);
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
2020-04-17 12:54:17 +09:00
|
|
|
let length: Value<Number> = Value::from_raw(self.env, raw_length)?;
|
|
|
|
length.try_into()
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl Value<JsString> {
|
2020-05-01 02:26:56 +09:00
|
|
|
#[inline]
|
2020-04-17 12:54:17 +09:00
|
|
|
pub fn get_ref(&self) -> Result<&[u8]> {
|
2020-02-18 22:09:17 +09:00
|
|
|
let mut written_char_count: u64 = 0;
|
2020-04-17 12:54:17 +09:00
|
|
|
let len = self.len()? + 1;
|
2019-05-23 20:28:51 +09:00
|
|
|
let mut result = Vec::with_capacity(len);
|
|
|
|
unsafe {
|
|
|
|
let status = sys::napi_get_value_string_utf8(
|
2020-05-06 00:13:23 +09:00
|
|
|
self.env,
|
2019-05-23 20:28:51 +09:00
|
|
|
self.raw_value,
|
|
|
|
result.as_mut_ptr(),
|
2020-02-18 22:09:17 +09:00
|
|
|
len as u64,
|
|
|
|
&mut written_char_count,
|
2019-05-23 20:28:51 +09:00
|
|
|
);
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
2019-05-23 20:28:51 +09:00
|
|
|
let ptr = result.as_ptr();
|
|
|
|
mem::forget(result);
|
2020-04-17 12:54:17 +09:00
|
|
|
Ok(slice::from_raw_parts(
|
|
|
|
ptr as *const u8,
|
|
|
|
written_char_count as usize,
|
|
|
|
))
|
2019-05-23 20:28:51 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:26:56 +09:00
|
|
|
pub fn as_str(&self) -> Result<&str> {
|
2020-05-06 00:13:23 +09:00
|
|
|
str::from_utf8(self.get_ref()?).map_err(|e| Error {
|
|
|
|
status: Status::GenericFailure,
|
|
|
|
reason: Some(format!("{:?}", e)),
|
|
|
|
})
|
2020-05-01 02:26:56 +09:00
|
|
|
}
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
pub fn get_ref_mut(&mut self) -> Result<&mut [u8]> {
|
2020-04-09 00:58:50 +09:00
|
|
|
let mut written_char_count: u64 = 0;
|
2020-04-17 12:54:17 +09:00
|
|
|
let len = self.len()? + 1;
|
2020-04-09 00:58:50 +09:00
|
|
|
let mut result = Vec::with_capacity(len);
|
|
|
|
unsafe {
|
|
|
|
let status = sys::napi_get_value_string_utf8(
|
2020-05-06 00:13:23 +09:00
|
|
|
self.env,
|
2020-04-09 00:58:50 +09:00
|
|
|
self.raw_value,
|
|
|
|
result.as_mut_ptr(),
|
|
|
|
len as u64,
|
|
|
|
&mut written_char_count,
|
|
|
|
);
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
2020-04-09 00:58:50 +09:00
|
|
|
let ptr = result.as_ptr();
|
|
|
|
mem::forget(result);
|
2020-04-17 12:54:17 +09:00
|
|
|
Ok(slice::from_raw_parts_mut(
|
|
|
|
ptr as *mut _,
|
|
|
|
written_char_count as usize,
|
|
|
|
))
|
2020-04-09 00:58:50 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl TryFrom<Value<JsString>> for Vec<u16> {
|
2020-04-17 12:54:17 +09:00
|
|
|
type Error = Error;
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn try_from(value: Value<JsString>) -> Result<Vec<u16>> {
|
2020-04-26 19:46:56 +09:00
|
|
|
let mut result = Vec::with_capacity(value.len()? + 1); // Leave room for trailing null byte
|
2018-04-28 17:26:38 +09:00
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let mut written_char_count = 0;
|
|
|
|
let status = sys::napi_get_value_string_utf16(
|
2020-05-06 00:13:23 +09:00
|
|
|
value.env,
|
2020-04-26 19:46:56 +09:00
|
|
|
value.raw_value,
|
2018-04-28 17:26:38 +09:00
|
|
|
result.as_mut_ptr(),
|
2020-02-18 22:09:17 +09:00
|
|
|
result.capacity() as u64,
|
2018-04-28 17:26:38 +09:00
|
|
|
&mut written_char_count,
|
|
|
|
);
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
2020-02-18 22:09:17 +09:00
|
|
|
result.set_len(written_char_count as usize);
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
Ok(result)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl TryFrom<Value<Number>> for usize {
|
2020-04-17 12:54:17 +09:00
|
|
|
type Error = Error;
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn try_from(value: Value<Number>) -> Result<usize> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut result = 0;
|
2020-05-06 00:13:23 +09:00
|
|
|
let status = unsafe { sys::napi_get_value_int64(value.env, value.raw_value, &mut result) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(result as usize)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl TryFrom<Value<Number>> for u32 {
|
2020-04-26 19:46:56 +09:00
|
|
|
type Error = Error;
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn try_from(value: Value<Number>) -> Result<u32> {
|
2020-04-26 19:46:56 +09:00
|
|
|
let mut result = 0;
|
2020-05-06 00:13:23 +09:00
|
|
|
let status = unsafe { sys::napi_get_value_uint32(value.env, value.raw_value, &mut result) };
|
2020-04-26 19:46:56 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl TryFrom<Value<Number>> for i32 {
|
2020-04-26 19:46:56 +09:00
|
|
|
type Error = Error;
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn try_from(value: Value<Number>) -> Result<i32> {
|
2020-04-26 19:46:56 +09:00
|
|
|
let mut result = 0;
|
2020-05-06 00:13:23 +09:00
|
|
|
let status = unsafe { sys::napi_get_value_int32(value.env, value.raw_value, &mut result) };
|
2020-04-26 19:46:56 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl TryFrom<Value<Number>> for i64 {
|
2020-04-17 12:54:17 +09:00
|
|
|
type Error = Error;
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn try_from(value: Value<Number>) -> Result<i64> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut result = 0;
|
2020-05-06 00:13:23 +09:00
|
|
|
let status = unsafe { sys::napi_get_value_int64(value.env, value.raw_value, &mut result) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(result)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl TryFrom<Value<Number>> for f64 {
|
2020-04-17 12:54:17 +09:00
|
|
|
type Error = Error;
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
fn try_from(value: Value<Number>) -> Result<f64> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let mut result = 0_f64;
|
2020-05-06 00:13:23 +09:00
|
|
|
let status = unsafe { sys::napi_get_value_double(value.env, value.raw_value, &mut result) };
|
2020-04-17 12:54:17 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(result)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl Value<Object> {
|
|
|
|
pub fn set_property<K, V>(&mut self, key: Value<K>, value: Value<V>) -> Result<()> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_set_property(
|
|
|
|
self.raw_env(),
|
|
|
|
self.raw_value(),
|
|
|
|
key.raw_value,
|
|
|
|
value.raw_value,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn set_named_property<T, V: Into<Value<T>>>(&mut self, name: &str, value: V) -> Result<()> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let key = CString::new(name)?;
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_set_named_property(
|
|
|
|
self.raw_env(),
|
|
|
|
self.raw_value(),
|
|
|
|
key.as_ptr(),
|
|
|
|
value.into().raw_value,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_named_property<T: ValueType>(&self, name: &str) -> Result<Value<T>> {
|
|
|
|
let key = CString::new(name)?;
|
|
|
|
let mut raw_value = ptr::null_mut();
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_get_named_property(
|
|
|
|
self.raw_env(),
|
|
|
|
self.raw_value(),
|
|
|
|
key.as_ptr(),
|
|
|
|
&mut raw_value,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
check_status(status)?;
|
2020-04-17 12:54:17 +09:00
|
|
|
Value::<T>::from_raw(self.env, raw_value)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2019-01-27 07:33:47 +09:00
|
|
|
pub fn get_property_names<T: ValueType>(&self) -> Result<Value<T>> {
|
|
|
|
let mut raw_value = ptr::null_mut();
|
2019-05-16 01:41:22 +09:00
|
|
|
let status =
|
|
|
|
unsafe { sys::napi_get_property_names(self.raw_env(), self.raw_value(), &mut raw_value) };
|
2019-01-27 07:33:47 +09:00
|
|
|
check_status(status)?;
|
2020-04-17 12:54:17 +09:00
|
|
|
Value::<T>::from_raw(self.env, raw_value)
|
2019-01-27 07:33:47 +09:00
|
|
|
}
|
|
|
|
|
2018-04-28 17:26:38 +09:00
|
|
|
pub fn set_index<'a, T>(&mut self, index: usize, value: Value<T>) -> Result<()> {
|
2020-05-06 00:13:23 +09:00
|
|
|
self.set_property(Env::from_raw(self.env).create_int64(index as i64)?, value)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
|
2019-01-27 07:33:47 +09:00
|
|
|
pub fn get_index<T: ValueType>(&self, index: u32) -> Result<Value<T>> {
|
|
|
|
let mut raw_value = ptr::null_mut();
|
2019-05-16 01:41:22 +09:00
|
|
|
let status =
|
|
|
|
unsafe { sys::napi_get_element(self.raw_env(), self.raw_value(), index, &mut raw_value) };
|
2019-01-27 07:33:47 +09:00
|
|
|
check_status(status)?;
|
2020-04-17 12:54:17 +09:00
|
|
|
Value::<T>::from_raw(self.env, raw_value)
|
2019-01-27 07:33:47 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_array(&self) -> Result<bool> {
|
|
|
|
let mut is_array = false;
|
2019-05-16 01:41:22 +09:00
|
|
|
let status = unsafe { sys::napi_is_array(self.raw_env(), self.raw_value(), &mut is_array) };
|
2019-01-27 07:33:47 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(is_array)
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:10:06 +09:00
|
|
|
pub fn is_buffer(&self) -> Result<bool> {
|
|
|
|
let mut is_buffer = false;
|
|
|
|
let status = unsafe { sys::napi_is_buffer(self.raw_env(), self.raw_value(), &mut is_buffer) };
|
|
|
|
check_status(status)?;
|
|
|
|
Ok(is_buffer)
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
pub fn to_buffer(&self) -> Result<Value<Buffer>> {
|
2020-01-16 23:10:06 +09:00
|
|
|
Value::from_raw(self.env, self.raw_value)
|
|
|
|
}
|
|
|
|
|
2019-01-27 07:33:47 +09:00
|
|
|
pub fn get_array_length(&self) -> Result<u32> {
|
|
|
|
if self.is_array()? != true {
|
|
|
|
return Err(Error {
|
2019-05-16 01:41:22 +09:00
|
|
|
status: Status::ArrayExpected,
|
2020-05-06 00:13:23 +09:00
|
|
|
reason: Some("Object is not array".to_owned()),
|
2019-05-16 01:41:22 +09:00
|
|
|
});
|
2019-01-27 07:33:47 +09:00
|
|
|
}
|
|
|
|
let mut length: u32 = 0;
|
2019-05-16 01:41:22 +09:00
|
|
|
let status =
|
|
|
|
unsafe { sys::napi_get_array_length(self.raw_env(), self.raw_value(), &mut length) };
|
2019-01-27 07:33:47 +09:00
|
|
|
check_status(status)?;
|
|
|
|
Ok(length)
|
|
|
|
}
|
|
|
|
|
2018-04-28 17:26:38 +09:00
|
|
|
fn raw_value(&self) -> sys::napi_value {
|
|
|
|
self.raw_value
|
|
|
|
}
|
|
|
|
|
|
|
|
fn raw_env(&self) -> sys::napi_env {
|
2020-05-06 00:13:23 +09:00
|
|
|
self.env
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl AsRef<[u8]> for Value<Buffer> {
|
2020-04-20 01:43:48 +09:00
|
|
|
fn as_ref(&self) -> &[u8] {
|
|
|
|
self.deref()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl Deref for Value<Buffer> {
|
2019-05-16 01:41:22 +09:00
|
|
|
type Target = [u8];
|
|
|
|
|
|
|
|
fn deref(&self) -> &[u8] {
|
2020-02-18 22:09:17 +09:00
|
|
|
unsafe { slice::from_raw_parts(self.value.data, self.value.size as usize) }
|
2019-05-16 01:41:22 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl DerefMut for Value<Buffer> {
|
2019-05-16 01:41:22 +09:00
|
|
|
fn deref_mut(&mut self) -> &mut [u8] {
|
2020-04-09 00:58:50 +09:00
|
|
|
unsafe { slice::from_raw_parts_mut(self.value.data as *mut _, self.value.size as usize) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl Deref for Value<ArrayBuffer> {
|
2020-04-09 00:58:50 +09:00
|
|
|
type Target = [u8];
|
|
|
|
|
|
|
|
fn deref(&self) -> &[u8] {
|
|
|
|
unsafe { slice::from_raw_parts(self.value.data, self.value.size as usize) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl DerefMut for Value<ArrayBuffer> {
|
2020-04-09 00:58:50 +09:00
|
|
|
fn deref_mut(&mut self) -> &mut [u8] {
|
|
|
|
unsafe { slice::from_raw_parts_mut(self.value.data as *mut _, self.value.size as usize) }
|
2019-05-16 01:41:22 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl Value<Function> {
|
|
|
|
pub fn call(&self, this: Option<&Value<Object>>, args: &[Value<Any>]) -> Result<Value<Any>> {
|
2018-04-28 17:26:38 +09:00
|
|
|
let raw_this = this
|
|
|
|
.map(|v| v.into_raw())
|
2020-05-06 00:13:23 +09:00
|
|
|
.or_else(|| {
|
|
|
|
Env::from_raw(self.env)
|
|
|
|
.get_undefined()
|
|
|
|
.ok()
|
|
|
|
.map(|u| u.into_raw())
|
|
|
|
})
|
|
|
|
.ok_or(Error {
|
|
|
|
status: Status::Unknown,
|
|
|
|
reason: Some("Get raw this failed".to_owned()),
|
|
|
|
})?;
|
2020-02-18 22:09:17 +09:00
|
|
|
let mut raw_args = unsafe { mem::MaybeUninit::<[sys::napi_value; 8]>::uninit().assume_init() };
|
2018-04-28 17:26:38 +09:00
|
|
|
for (i, arg) in args.into_iter().enumerate() {
|
|
|
|
raw_args[i] = arg.raw_value;
|
|
|
|
}
|
|
|
|
let mut return_value = ptr::null_mut();
|
|
|
|
let status = unsafe {
|
|
|
|
sys::napi_call_function(
|
2020-05-06 00:13:23 +09:00
|
|
|
self.env,
|
2018-04-28 17:26:38 +09:00
|
|
|
raw_this,
|
|
|
|
self.raw_value,
|
2020-02-18 22:09:17 +09:00
|
|
|
args.len() as u64,
|
2018-04-28 17:26:38 +09:00
|
|
|
&raw_args[0],
|
|
|
|
&mut return_value,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
check_status(status)?;
|
|
|
|
|
2020-04-17 12:54:17 +09:00
|
|
|
Value::from_raw(self.env, return_value)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
impl Value<Any> {
|
|
|
|
pub fn get_type(&self) -> Result<sys::napi_valuetype> {
|
|
|
|
get_raw_type(self.env, self.raw_value)
|
2020-01-16 23:10:06 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-28 17:26:38 +09:00
|
|
|
impl<T> Drop for Ref<T> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
let mut ref_count = 0;
|
|
|
|
let status = sys::napi_reference_unref(self.raw_env, self.raw_ref, &mut ref_count);
|
|
|
|
debug_assert!(Status::from(status) == Status::Ok);
|
|
|
|
|
|
|
|
if ref_count == 0 {
|
|
|
|
let status = sys::napi_delete_reference(self.raw_env, self.raw_ref);
|
|
|
|
debug_assert!(Status::from(status) == Status::Ok);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Property {
|
|
|
|
pub fn new(name: &str) -> Self {
|
|
|
|
Property {
|
|
|
|
name: RustString::from(name),
|
|
|
|
raw_descriptor: sys::napi_property_descriptor {
|
|
|
|
utf8name: ptr::null_mut(),
|
|
|
|
name: ptr::null_mut(),
|
|
|
|
method: None,
|
|
|
|
getter: None,
|
|
|
|
setter: None,
|
|
|
|
value: ptr::null_mut(),
|
|
|
|
attributes: sys::napi_property_attributes::napi_default,
|
|
|
|
data: ptr::null_mut(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_value<T>(mut self, value: Value<T>) -> Self {
|
|
|
|
self.raw_descriptor.value = value.raw_value;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_method(mut self, callback: Callback) -> Self {
|
|
|
|
self.raw_descriptor.method = Some(callback);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_getter(mut self, callback: Callback) -> Self {
|
|
|
|
self.raw_descriptor.getter = Some(callback);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-04-03 01:09:44 +09:00
|
|
|
fn into_raw(mut self, env: &Env) -> Result<sys::napi_property_descriptor> {
|
|
|
|
self.raw_descriptor.name = env.create_string(&self.name)?.into_raw();
|
|
|
|
Ok(self.raw_descriptor)
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: 'static> TaggedObject<T> {
|
|
|
|
fn new(object: T) -> Self {
|
|
|
|
TaggedObject {
|
|
|
|
type_id: TypeId::of::<T>(),
|
|
|
|
object: Some(object),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:13:23 +09:00
|
|
|
#[inline]
|
2018-04-28 17:26:38 +09:00
|
|
|
fn check_status(code: sys::napi_status) -> Result<()> {
|
|
|
|
let status = Status::from(code);
|
|
|
|
match status {
|
|
|
|
Status::Ok => Ok(()),
|
2020-05-06 00:13:23 +09:00
|
|
|
_ => Err(Error::from_status(status)),
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-21 01:45:30 +09:00
|
|
|
unsafe extern "C" fn raw_finalize<T>(
|
2018-04-28 17:26:38 +09:00
|
|
|
_raw_env: sys::napi_env,
|
|
|
|
finalize_data: *mut c_void,
|
|
|
|
_finalize_hint: *mut c_void,
|
|
|
|
) {
|
2020-02-21 01:45:30 +09:00
|
|
|
let tagged_object: *mut TaggedObject<T> = mem::transmute(finalize_data);
|
|
|
|
Box::from_raw(tagged_object);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe extern "C" fn drop_buffer(env: sys::napi_env, finalize_data: *mut c_void, len: *mut c_void) {
|
|
|
|
let length = Box::from_raw(len as *mut u64);
|
|
|
|
let length = length.as_ref();
|
|
|
|
let length = *length as usize;
|
|
|
|
let _ = Vec::from_raw_parts(finalize_data as *mut u8, length, length);
|
|
|
|
let mut changed = 0;
|
|
|
|
let ajust_external_memory_status =
|
|
|
|
sys::napi_adjust_external_memory(env, -(length as i64), &mut changed);
|
|
|
|
debug_assert!(Status::from(ajust_external_memory_status) == Status::Ok);
|
2018-04-28 17:26:38 +09:00
|
|
|
}
|