use std::any::type_name; use std::ops::{Deref, DerefMut}; use std::ptr; use super::Object; use crate::{ bindgen_runtime::{FromNapiValue, TypeName, ValidateNapiValue}, check_status, sys, Env, NapiRaw, NapiValue, ValueType, }; pub type This = T; pub struct ClassInstance { pub value: sys::napi_value, inner: &'static mut T, } impl ClassInstance { #[doc(hidden)] pub fn new(value: sys::napi_value, inner: &'static mut T) -> Self { Self { value, inner } } pub fn as_object(&self, env: Env) -> Object { unsafe { Object::from_raw_unchecked(env.raw(), self.value) } } } impl NapiRaw for ClassInstance { unsafe fn raw(&self) -> sys::napi_value { self.value } } impl TypeName for ClassInstance where &'static T: TypeName, { fn type_name() -> &'static str { type_name::<&T>() } fn value_type() -> ValueType { <&T>::value_type() } } impl ValidateNapiValue for ClassInstance where &'static T: ValidateNapiValue, { unsafe fn validate( env: sys::napi_env, napi_val: sys::napi_value, ) -> crate::Result { unsafe { <&T>::validate(env, napi_val) } } } impl FromNapiValue for ClassInstance { unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result { let mut value = ptr::null_mut(); check_status!( unsafe { sys::napi_unwrap(env, napi_val, &mut value) }, "Unwrap value [{}] from class failed", type_name::(), )?; let value = unsafe { Box::from_raw(value as *mut T) }; Ok(Self { value: napi_val, inner: Box::leak(value), }) } } impl Deref for ClassInstance { type Target = T; fn deref(&self) -> &Self::Target { self.inner } } impl DerefMut for ClassInstance { fn deref_mut(&mut self) -> &mut T { self.inner } } impl AsRef for ClassInstance { fn as_ref(&self) -> &T { self.inner } } impl AsMut for ClassInstance { fn as_mut(&mut self) -> &mut T { self.inner } }