1 | use std::any::type_name; |
2 | use std::ops::{Deref, DerefMut}; |
3 | use std::ptr; |
4 | |
5 | use super::Object; |
6 | use crate::{ |
7 | bindgen_runtime::{FromNapiValue, TypeName, ValidateNapiValue}, |
8 | check_status, sys, Env, NapiRaw, NapiValue, ValueType, |
9 | }; |
10 | |
11 | pub type This<T = Object> = T; |
12 | |
13 | pub struct ClassInstance<T: 'static> { |
14 | pub value: sys::napi_value, |
15 | inner: &'static mut T, |
16 | } |
17 | |
18 | impl<T: 'static> ClassInstance<T> { |
19 | #[doc (hidden)] |
20 | pub fn new(value: sys::napi_value, inner: &'static mut T) -> Self { |
21 | Self { value, inner } |
22 | } |
23 | |
24 | pub fn as_object(&self, env: Env) -> Object { |
25 | unsafe { Object::from_raw_unchecked(env.raw(), self.value) } |
26 | } |
27 | } |
28 | |
29 | impl<T: 'static> NapiRaw for ClassInstance<T> { |
30 | unsafe fn raw(&self) -> sys::napi_value { |
31 | self.value |
32 | } |
33 | } |
34 | |
35 | impl<T: 'static> TypeName for ClassInstance<T> |
36 | where |
37 | &'static T: TypeName, |
38 | { |
39 | fn type_name() -> &'static str { |
40 | type_name::<&T>() |
41 | } |
42 | |
43 | fn value_type() -> ValueType { |
44 | <&T>::value_type() |
45 | } |
46 | } |
47 | |
48 | impl<T: 'static> ValidateNapiValue for ClassInstance<T> |
49 | where |
50 | &'static T: ValidateNapiValue, |
51 | { |
52 | unsafe fn validate( |
53 | env: sys::napi_env, |
54 | napi_val: sys::napi_value, |
55 | ) -> crate::Result<sys::napi_value> { |
56 | unsafe { <&T>::validate(env, napi_val) } |
57 | } |
58 | } |
59 | |
60 | impl<T: 'static> FromNapiValue for ClassInstance<T> { |
61 | unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result<Self> { |
62 | let mut value: *mut c_void = ptr::null_mut(); |
63 | check_status!( |
64 | unsafe { sys::napi_unwrap(env, napi_val, &mut value) }, |
65 | "Unwrap value [ {}] from class failed" , |
66 | type_name::<T>(), |
67 | )?; |
68 | let value: Box = unsafe { Box::from_raw(value as *mut T) }; |
69 | Ok(Self { |
70 | value: napi_val, |
71 | inner: Box::leak(value), |
72 | }) |
73 | } |
74 | } |
75 | |
76 | impl<T: 'static> Deref for ClassInstance<T> { |
77 | type Target = T; |
78 | |
79 | fn deref(&self) -> &Self::Target { |
80 | self.inner |
81 | } |
82 | } |
83 | |
84 | impl<T: 'static> DerefMut for ClassInstance<T> { |
85 | fn deref_mut(&mut self) -> &mut T { |
86 | self.inner |
87 | } |
88 | } |
89 | |
90 | impl<T: 'static> AsRef<T> for ClassInstance<T> { |
91 | fn as_ref(&self) -> &T { |
92 | self.inner |
93 | } |
94 | } |
95 | |
96 | impl<T: 'static> AsMut<T> for ClassInstance<T> { |
97 | fn as_mut(&mut self) -> &mut T { |
98 | self.inner |
99 | } |
100 | } |
101 | |