1use std::mem::transmute;
4use std::ops::Deref;
5use std::os::raw::c_void;
6use std::ptr::NonNull;
7
8use deno_core::v8;
9
10#[repr(transparent)]
13#[derive(Clone, Copy, Debug)]
14pub struct NapiValue<'s>(
15 Option<NonNull<v8::Value>>,
16 std::marker::PhantomData<&'s ()>,
17);
18
19pub type napi_value<'s> = NapiValue<'s>;
20
21impl<'s> Deref for napi_value<'s> {
22 type Target = Option<v8::Local<'s, v8::Value>>;
23 fn deref(&self) -> &Self::Target {
24 unsafe { transmute::<&Self, &Self::Target>(self) }
27 }
28}
29
30impl<'s, T> From<v8::Local<'s, T>> for napi_value<'s>
31where
32 v8::Local<'s, T>: Into<v8::Local<'s, v8::Value>>,
33{
34 fn from(v: v8::Local<'s, T>) -> Self {
35 Self(Some(NonNull::from(&*v.into())), std::marker::PhantomData)
36 }
37}
38
39impl<'s, T> From<Option<v8::Local<'s, T>>> for napi_value<'s>
40where
41 v8::Local<'s, T>: Into<v8::Local<'s, v8::Value>>,
42{
43 fn from(v: Option<v8::Local<'s, T>>) -> Self {
44 if let Some(v) = v {
45 NapiValue::from(v)
46 } else {
47 Self(None, std::marker::PhantomData)
48 }
49 }
50}
51
52const _: () = {
53 assert!(
54 std::mem::size_of::<napi_value>() == std::mem::size_of::<*mut c_void>()
55 );
56 unsafe {
58 type Src<'a> = napi_value<'a>;
59 type Dst = usize;
60 assert!(std::mem::size_of::<Src>() == std::mem::size_of::<Dst>());
61 union Transmute<'a> {
62 src: Src<'a>,
63 dst: Dst,
64 }
65 Transmute {
66 src: NapiValue(None, std::marker::PhantomData),
67 }
68 .dst
69 };
70};