diff --git a/crates/nodex-api/src/env.rs b/crates/nodex-api/src/env.rs index bf1e7cb..d051a09 100644 --- a/crates/nodex-api/src/env.rs +++ b/crates/nodex-api/src/env.rs @@ -659,7 +659,19 @@ impl NapiEnv { /// napi_set_instance_data(). If no data is set, the call will succeed and data will be set to /// NULL. #[inline] - pub fn get_instance_data(&self) -> NapiResult> { + pub fn get_instance_data(&self) -> NapiResult> { + let data = napi_call!(=napi_get_instance_data, *self) as *mut T; + if data.is_null() { + Ok(None) + } else { + unsafe { Ok(Some(&*(data as *const T))) } + } + } + + #[cfg(feature = "v6")] + #[inline] + /// Mutable access variant of instance data; use when data must be updated in place. + pub fn get_instance_data_mut(&mut self) -> NapiResult> { let data = napi_call!(=napi_get_instance_data, *self) as *mut T; if data.is_null() { Ok(None) diff --git a/crates/nodex-api/src/mac.rs b/crates/nodex-api/src/mac.rs index ef70d90..23095e9 100644 --- a/crates/nodex-api/src/mac.rs +++ b/crates/nodex-api/src/mac.rs @@ -45,7 +45,8 @@ macro_rules! napi_call { unsafe { let mut result = std::mem::MaybeUninit::uninit(); let status = $crate::api::$napi($($args),+, result.as_mut_ptr()); - (status, result.assume_init()) + let value = status.ok().then(|| result.assume_init()); + (status, value) } }; diff --git a/crates/nodex-api/src/reference.rs b/crates/nodex-api/src/reference.rs index 389f58e..2aae6aa 100644 --- a/crates/nodex-api/src/reference.rs +++ b/crates/nodex-api/src/reference.rs @@ -1,6 +1,6 @@ use crate::{api, prelude::*}; -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct NapiRef(NapiEnv, napi_ref); impl NapiRef { diff --git a/crates/nodex-api/src/value/external.rs b/crates/nodex-api/src/value/external.rs index bdea239..4e67968 100644 --- a/crates/nodex-api/src/value/external.rs +++ b/crates/nodex-api/src/value/external.rs @@ -43,7 +43,13 @@ impl JsExternal { } /// Access the underlaying data. - pub fn get(&self) -> NapiResult<&mut T> { + pub fn get(&self) -> NapiResult<&T> { + let ext = napi_call!(=napi_get_value_external, self.env(), self.raw()); + unsafe { Ok(&*(ext as *const T)) } + } + + /// Mutable access to the underlying external data. + pub fn get_mut(&mut self) -> NapiResult<&mut T> { let ext = napi_call!(=napi_get_value_external, self.env(), self.raw()); unsafe { Ok(&mut *(ext as *mut T)) } } diff --git a/crates/nodex-api/src/value/mod.rs b/crates/nodex-api/src/value/mod.rs index 48683a8..5c68efd 100644 --- a/crates/nodex-api/src/value/mod.rs +++ b/crates/nodex-api/src/value/mod.rs @@ -441,10 +441,26 @@ pub trait NapiValueT: NapiValueCheck + Sized { /// /// NB: if a there is no wrap or the wrap is just removed by NapiValue::remove_wrap, return /// None. - fn unwrap(&self) -> NapiResult> { + fn unwrap(&self) -> NapiResult> { let (status, value) = napi_call!(?napi_unwrap, self.env(), self.raw()); match status { - NapiStatus::Ok => unsafe { Ok(Some(&mut *(value as *mut T))) }, + NapiStatus::Ok => match value { + Some(value) => unsafe { Ok(Some(&*(value as *const T))) }, + None => Ok(None), + }, + NapiStatus::InvalidArg => Ok(None), + err => Err(err), + } + } + + /// Mutable variant of unwrap. + fn unwrap_mut(&mut self) -> NapiResult> { + let (status, value) = napi_call!(?napi_unwrap, self.env(), self.raw()); + match status { + NapiStatus::Ok => match value { + Some(value) => unsafe { Ok(Some(&mut *(value as *mut T))) }, + None => Ok(None), + }, NapiStatus::InvalidArg => Ok(None), err => Err(err), } diff --git a/crates/nodex-api/src/work.rs b/crates/nodex-api/src/work.rs index ac1778b..5d724f4 100644 --- a/crates/nodex-api/src/work.rs +++ b/crates/nodex-api/src/work.rs @@ -61,11 +61,13 @@ impl NapiAsyncWork { unsafe { let mut pair: Box<( Box, - Box, + Box NapiResult<()>>, T, )> = Box::from_raw(data as _); let mut complete = pair.1; - complete(env, status, pair.2); + if let Err(err) = complete(env, status, pair.2) { + log::error!("NapiAsyncWork::complete: {}", err); + } } } diff --git a/examples/demo/src/lib.rs b/examples/demo/src/lib.rs index b86610e..eeefd37 100644 --- a/examples/demo/src/lib.rs +++ b/examples/demo/src/lib.rs @@ -2,7 +2,7 @@ use nodex::prelude::*; nodex::napi_module!(init); -fn init(env: NapiEnv, mut exports: JsObject) -> NapiResult<()> { +fn init(mut env: NapiEnv, mut exports: JsObject) -> NapiResult<()> { nodex::napi_guard!(env.napi_version()?); let mut obj = env.object()?; @@ -203,7 +203,7 @@ fn init(env: NapiEnv, mut exports: JsObject) -> NapiResult<()> { let value = env.get_instance_data::()?; println!("get instance data: {:?}", value); - if let Ok(Some(data)) = env.get_instance_data::() { + if let Ok(Some(data)) = env.get_instance_data_mut::() { *data = 200; } let value = env.get_instance_data::()?;