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)),
|
||||
("JsUnknown", ("unknown", false, false)),
|
||||
("This", ("this", false, false))
|
||||
("This", ("this", false, false)),
|
||||
("Rc", ("{}", false, false)),
|
||||
("Arc", ("{}", false, false)),
|
||||
("Mutex", ("{}", false, false)),
|
||||
]);
|
||||
|
||||
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};
|
||||
|
||||
|
@ -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