napi/js_values/
external.rs1use std::{marker::PhantomData, ptr};
2
3use crate::{
4 bindgen_prelude::{
5 sys, External, ExternalRef, FromNapiValue, Result, Status, TypeName, ValidateNapiValue,
6 },
7 check_status, Error, JsValue, Value, ValueType,
8};
9
10pub struct JsExternal<'env>(pub(crate) Value, PhantomData<&'env ()>);
15
16impl<'env> TypeName for JsExternal<'env> {
17 fn type_name() -> &'static str {
18 "External"
19 }
20
21 fn value_type() -> ValueType {
22 ValueType::External
23 }
24}
25
26impl<'env> ValidateNapiValue for JsExternal<'env> {}
27
28impl<'env> FromNapiValue for JsExternal<'env> {
29 unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
30 Ok(Self(
31 Value {
32 env,
33 value: napi_val,
34 value_type: ValueType::External,
35 },
36 PhantomData,
37 ))
38 }
39}
40
41impl<'env> JsValue<'env> for JsExternal<'env> {
42 fn value(&self) -> Value {
43 self.0
44 }
45}
46
47impl<'env> JsExternal<'env> {
48 pub fn get_value<T: 'static>(&self) -> Result<&mut T> {
52 self.get_static_value::<T>().map(|ext| ext.as_mut())
53 }
54
55 pub fn create_ref<T: 'static>(&self) -> Result<ExternalRef<T>> {
59 let mut ref_ = ptr::null_mut();
60 let external = self.get_static_value()?;
61 check_status!(
62 unsafe { sys::napi_create_reference(self.0.env, self.0.value, 1, &mut ref_) },
63 "Failed to create reference on external value"
64 )?;
65 Ok(ExternalRef {
66 obj: external,
67 raw: ref_,
68 env: self.0.env,
69 })
70 }
71
72 #[inline]
73 fn get_static_value<T: 'static>(&self) -> Result<&'static mut External<T>> {
74 let mut unknown_tagged_object = ptr::null_mut();
75 check_status!(
76 unsafe { sys::napi_get_value_external(self.0.env, self.0.value, &mut unknown_tagged_object) },
77 "Failed to get external value"
78 )?;
79
80 match unsafe { External::from_raw_impl(unknown_tagged_object) } {
81 Some(external) => Ok(external),
82 None => Err(Error::new(
83 Status::InvalidArg,
84 format!(
85 "<{}> on `External` is not the type of wrapped object",
86 std::any::type_name::<T>()
87 ),
88 )),
89 }
90 }
91}