Skip to content

Commit

Permalink
style: share unsafe code in a private helper, fix clippy lint
Browse files Browse the repository at this point in the history
  • Loading branch information
dherman committed Feb 3, 2025
1 parent 8ae43c0 commit 052a9d5
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 22 deletions.
32 changes: 14 additions & 18 deletions crates/neon/src/types_impl/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,10 @@ impl<T: 'static> ValueInternal for JsBox<T> {
/// until the application terminates, only that its lifetime is indefinite.
impl<T: Finalize + 'static> JsBox<T> {
/// Constructs a new `JsBox` containing `value`.
pub fn new<'a, C>(cx: &mut C, value: T) -> Handle<'a, JsBox<T>>
where
C: Context<'a>,
T: 'static,
{
pub fn new<'cx, C: Context<'cx>>(cx: &mut C, value: T) -> Handle<'cx, JsBox<T>> {
// This function will execute immediately before the `JsBox` is garbage collected.
// It unwraps the `napi_external`, downcasts the `BoxAny` and moves the type
// out of the `Box`. Lastly, it calls the trait method `Finalize::fianlize` of the
// out of the `Box`. Lastly, it calls the trait method `Finalize::finalize` of the
// contained value `T`.
fn finalizer<U: Finalize + 'static>(env: raw::Env, data: BoxAny) {
let data = *data.downcast::<U>().unwrap();
Expand All @@ -250,29 +246,29 @@ impl<T: Finalize + 'static> JsBox<T> {
Cx::with_context(env, move |mut cx| data.finalize(&mut cx));
}

let v = Box::new(value) as BoxAny;
// Since this value was just constructed, we know it is `T`
let raw_data = &*v as *const dyn Any as *const T;
let local = unsafe { external::create(cx.env().to_raw(), v, finalizer::<T>) };

Handle::new_internal(Self(JsBoxInner { local, raw_data }))
Self::create_external(cx, value, finalizer::<T>)
}
}

impl<T: 'static> JsBox<T> {
pub(crate) fn manually_finalize<'a, C>(cx: &mut C, value: T) -> Handle<'a, JsBox<T>>
where
C: Context<'a>,
T: 'static,
{
pub(crate) fn manually_finalize<'cx>(cx: &mut Cx<'cx>, value: T) -> Handle<'cx, JsBox<T>> {
fn finalizer(_env: raw::Env, _data: BoxAny) {}

Self::create_external(cx, value, finalizer)
}

fn create_external<'cx, C: Context<'cx>>(
cx: &mut C,
value: T,
finalizer: fn(raw::Env, BoxAny),
) -> Handle<'cx, JsBox<T>> {
let v = Box::new(value) as BoxAny;

// Since this value was just constructed, we know it is `T`
let raw_data = &*v as *const dyn Any as *const T;
let local = unsafe { external::create(cx.env().to_raw(), v, finalizer) };

Handle::new_internal(Self(JsBoxInner { local, raw_data }))
Handle::new_internal(JsBox(JsBoxInner { local, raw_data }))
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/neon/src/types_impl/extract/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl<'cx, T: 'static> TryFromJs<'cx> for Rc<T> {
v: Handle<'cx, JsValue>,
) -> NeonResult<Result<Self, Self::Error>> {
match v.downcast::<JsBox<Rc<T>>, _>(cx) {
Ok(v) => Ok(Ok(JsBox::deref(&v).clone())),
Ok(v) => Ok(Ok(Rc::clone(&v))),
Err(_) => Ok(Err(TypeExpected::new())),
}
}
Expand All @@ -108,7 +108,7 @@ impl<'cx, T: 'static> TryFromJs<'cx> for Arc<T> {
v: Handle<'cx, JsValue>,
) -> NeonResult<Result<Self, Self::Error>> {
match v.downcast::<JsBox<Arc<T>>, _>(cx) {
Ok(v) => Ok(Ok(JsBox::deref(&v).clone())),
Ok(v) => Ok(Ok(Arc::clone(&v))),
Err(_) => Ok(Err(TypeExpected::new())),
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/neon/src/types_impl/extract/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ impl<T> Sealed for Arc<T> {}

impl<T> Sealed for Rc<T> {}

impl<'a, T> Sealed for Ref<'a, T> {}
impl<T> Sealed for Ref<'_, T> {}

impl<'a, T> Sealed for RefMut<'a, T> {}
impl<T> Sealed for RefMut<'_, T> {}

impl_sealed!(u8, u16, u32, i8, i16, i32, f32, f64, bool, String, Date, Throw, Error,);

0 comments on commit 052a9d5

Please sign in to comment.