chore(napi): adds support for Rc<T>
/ Arc<T>
/ Mutex<T>
(#1573)
* Adds support for Rc/Arc/Mutex<T> * Fixes codegen * Fixes lint * Fix clippy --------- Co-authored-by: LongYinan <lynweklm@gmail.com>
This commit is contained in:
parent
5a1f229dba
commit
2f00e79873
2 changed files with 194 additions and 2 deletions
|
@ -205,7 +205,10 @@ static KNOWN_TYPES: Lazy<HashMap<&'static str, (&'static str, bool, bool)>> = La
|
||||||
("unknown", ("unknown", false, false)),
|
("unknown", ("unknown", false, false)),
|
||||||
("Unknown", ("unknown", false, false)),
|
("Unknown", ("unknown", false, false)),
|
||||||
("JsUnknown", ("unknown", false, false)),
|
("JsUnknown", ("unknown", false, false)),
|
||||||
("This", ("this", false, false))
|
("This", ("this", false, false)),
|
||||||
|
("Rc", ("{}", false, false)),
|
||||||
|
("Arc", ("{}", false, false)),
|
||||||
|
("Mutex", ("{}", false, false)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
map
|
map
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
use std::ptr;
|
use std::{
|
||||||
|
ptr,
|
||||||
|
rc::Rc,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{check_status, sys, Error, JsUnknown, NapiRaw, NapiValue, Result, Status, ValueType};
|
use crate::{check_status, sys, Error, JsUnknown, NapiRaw, NapiValue, Result, Status, ValueType};
|
||||||
|
|
||||||
|
@ -245,3 +249,188 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: TypeName> TypeName for Rc<T> {
|
||||||
|
fn type_name() -> &'static str {
|
||||||
|
T::type_name()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value_type() -> ValueType {
|
||||||
|
T::value_type()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ValidateNapiValue> ValidateNapiValue for Rc<T> {
|
||||||
|
unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result<sys::napi_value> {
|
||||||
|
let mut result = -1;
|
||||||
|
check_status!(
|
||||||
|
unsafe { sys::napi_typeof(env, napi_val, &mut result) },
|
||||||
|
"Failed to detect napi value type",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let received_type = ValueType::from(result);
|
||||||
|
if let Ok(validate_ret) = unsafe { T::validate(env, napi_val) } {
|
||||||
|
Ok(validate_ret)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(
|
||||||
|
Status::InvalidArg,
|
||||||
|
format!(
|
||||||
|
"Expect value to be Rc<{}>, but received {}",
|
||||||
|
T::value_type(),
|
||||||
|
received_type
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> FromNapiValue for Rc<T>
|
||||||
|
where
|
||||||
|
T: FromNapiValue,
|
||||||
|
{
|
||||||
|
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
|
||||||
|
let mut val_type = 0;
|
||||||
|
|
||||||
|
check_status!(
|
||||||
|
unsafe { sys::napi_typeof(env, napi_val, &mut val_type) },
|
||||||
|
"Failed to convert napi value into rust type `Rc<T>`",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(Rc::new(unsafe { T::from_napi_value(env, napi_val)? }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ToNapiValue for Rc<T>
|
||||||
|
where
|
||||||
|
T: ToNapiValue + Clone,
|
||||||
|
{
|
||||||
|
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
|
||||||
|
unsafe { T::to_napi_value(env, (*val).clone()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: TypeName> TypeName for Arc<T> {
|
||||||
|
fn type_name() -> &'static str {
|
||||||
|
T::type_name()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value_type() -> ValueType {
|
||||||
|
T::value_type()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ValidateNapiValue> ValidateNapiValue for Arc<T> {
|
||||||
|
unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result<sys::napi_value> {
|
||||||
|
let mut result = -1;
|
||||||
|
check_status!(
|
||||||
|
unsafe { sys::napi_typeof(env, napi_val, &mut result) },
|
||||||
|
"Failed to detect napi value type",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let received_type = ValueType::from(result);
|
||||||
|
if let Ok(validate_ret) = unsafe { T::validate(env, napi_val) } {
|
||||||
|
Ok(validate_ret)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(
|
||||||
|
Status::InvalidArg,
|
||||||
|
format!(
|
||||||
|
"Expect value to be Arc<{}>, but received {}",
|
||||||
|
T::value_type(),
|
||||||
|
received_type
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> FromNapiValue for Arc<T>
|
||||||
|
where
|
||||||
|
T: FromNapiValue,
|
||||||
|
{
|
||||||
|
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
|
||||||
|
let mut val_type = 0;
|
||||||
|
|
||||||
|
check_status!(
|
||||||
|
unsafe { sys::napi_typeof(env, napi_val, &mut val_type) },
|
||||||
|
"Failed to convert napi value into rust type `Arc<T>`",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(Arc::new(unsafe { T::from_napi_value(env, napi_val)? }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ToNapiValue for Arc<T>
|
||||||
|
where
|
||||||
|
T: ToNapiValue + Clone,
|
||||||
|
{
|
||||||
|
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
|
||||||
|
unsafe { T::to_napi_value(env, (*val).clone()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: TypeName> TypeName for Mutex<T> {
|
||||||
|
fn type_name() -> &'static str {
|
||||||
|
T::type_name()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value_type() -> ValueType {
|
||||||
|
T::value_type()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ValidateNapiValue> ValidateNapiValue for Mutex<T> {
|
||||||
|
unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result<sys::napi_value> {
|
||||||
|
let mut result = -1;
|
||||||
|
check_status!(
|
||||||
|
unsafe { sys::napi_typeof(env, napi_val, &mut result) },
|
||||||
|
"Failed to detect napi value type",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let received_type = ValueType::from(result);
|
||||||
|
if let Ok(validate_ret) = unsafe { T::validate(env, napi_val) } {
|
||||||
|
Ok(validate_ret)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(
|
||||||
|
Status::InvalidArg,
|
||||||
|
format!(
|
||||||
|
"Expect value to be Mutex<{}>, but received {}",
|
||||||
|
T::value_type(),
|
||||||
|
received_type
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> FromNapiValue for Mutex<T>
|
||||||
|
where
|
||||||
|
T: FromNapiValue,
|
||||||
|
{
|
||||||
|
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
|
||||||
|
let mut val_type = 0;
|
||||||
|
|
||||||
|
check_status!(
|
||||||
|
unsafe { sys::napi_typeof(env, napi_val, &mut val_type) },
|
||||||
|
"Failed to convert napi value into rust type `Mutex<T>`",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(Mutex::new(unsafe { T::from_napi_value(env, napi_val)? }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ToNapiValue for Mutex<T>
|
||||||
|
where
|
||||||
|
T: ToNapiValue + Clone,
|
||||||
|
{
|
||||||
|
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
|
||||||
|
unsafe {
|
||||||
|
match val.lock() {
|
||||||
|
Ok(inner) => T::to_napi_value(env, inner.clone()),
|
||||||
|
Err(_) => Err(Error::new(
|
||||||
|
Status::GenericFailure,
|
||||||
|
"Failed to acquire a lock",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue