From dbb93bb6a647662d63f01c2e5c910d8c61c0d4a4 Mon Sep 17 00:00:00 2001 From: "K.J. Valencik" Date: Mon, 16 Sep 2024 17:30:36 -0400 Subject: [PATCH 1/2] feat(neon): Add TryFromJs implementation for Root --- crates/neon/src/types_impl/extract/private.rs | 5 ++++- .../src/types_impl/extract/try_from_js.rs | 22 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/crates/neon/src/types_impl/extract/private.rs b/crates/neon/src/types_impl/extract/private.rs index 1226ecbee..d78f693b3 100644 --- a/crates/neon/src/types_impl/extract/private.rs +++ b/crates/neon/src/types_impl/extract/private.rs @@ -1,6 +1,7 @@ use crate::{ context::FunctionContext, - handle::Handle, + handle::{Handle, Root}, + object::Object, result::{NeonResult, Throw}, types::{ buffer::Binary, @@ -35,6 +36,8 @@ impl Sealed for &str {} impl<'cx, V: Value> Sealed for Handle<'cx, V> {} +impl Sealed for Root {} + impl Sealed for Option {} impl Sealed for Result {} diff --git a/crates/neon/src/types_impl/extract/try_from_js.rs b/crates/neon/src/types_impl/extract/try_from_js.rs index d7357b224..b65c042e7 100644 --- a/crates/neon/src/types_impl/extract/try_from_js.rs +++ b/crates/neon/src/types_impl/extract/try_from_js.rs @@ -7,7 +7,8 @@ use std::{convert::Infallible, ptr}; use crate::{ context::{internal::ContextInternal, Cx}, - handle::Handle, + handle::{Handle, Root}, + object::Object, result::{NeonResult, ResultExt, Throw}, sys, types::{ @@ -45,6 +46,25 @@ where from_js!(); } +impl<'cx, O> TryFromJs<'cx> for Root +where + O: Object, +{ + type Error = TypeExpected; + + fn try_from_js( + cx: &mut Cx<'cx>, + v: Handle<'cx, JsValue>, + ) -> NeonResult> { + Ok(match v.downcast::(cx) { + Ok(v) => Ok(v.root(cx)), + Err(_) => Err(TypeExpected::new()), + }) + } + + from_js!(); +} + impl<'cx, T> TryFromJs<'cx> for Option where T: TryFromJs<'cx>, From f6a6e92b79f73fba97c31c32e945bd153717f724 Mon Sep 17 00:00:00 2001 From: "K.J. Valencik" Date: Tue, 17 Sep 2024 09:58:01 -0400 Subject: [PATCH 2/2] feat(neon): Add TryIntoJs implementations for more types --- crates/neon/src/types_impl/extract/private.rs | 31 +++++++- .../src/types_impl/extract/try_into_js.rs | 73 ++++++++++++++++++- 2 files changed, 101 insertions(+), 3 deletions(-) diff --git a/crates/neon/src/types_impl/extract/private.rs b/crates/neon/src/types_impl/extract/private.rs index d78f693b3..af3687402 100644 --- a/crates/neon/src/types_impl/extract/private.rs +++ b/crates/neon/src/types_impl/extract/private.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use crate::{ context::FunctionContext, handle::{Handle, Root}, @@ -5,7 +7,7 @@ use crate::{ result::{NeonResult, Throw}, types::{ buffer::Binary, - extract::{ArrayBuffer, Buffer, Date, Error}, + extract::{ArrayBuffer, Buffer, Date, Error, TryIntoJs}, JsTypedArray, Value, }, }; @@ -34,6 +36,8 @@ impl Sealed for () {} impl Sealed for &str {} +impl Sealed for &String {} + impl<'cx, V: Value> Sealed for Handle<'cx, V> {} impl Sealed for Root {} @@ -49,6 +53,27 @@ where { } +impl Sealed for Box<[T]> +where + JsTypedArray: Value, + T: Binary, +{ +} + +impl Sealed for [T; N] +where + JsTypedArray: Value, + T: Binary, +{ +} + +impl Sealed for &Vec +where + JsTypedArray: Value, + T: Binary, +{ +} + impl Sealed for &[T] where JsTypedArray: Value, @@ -56,6 +81,10 @@ where { } +impl<'cx, T> Sealed for Arc where for<'a> &'a T: TryIntoJs<'cx> {} + +impl<'cx, T> Sealed for Box where T: TryIntoJs<'cx> {} + impl_sealed!( u8, u16, diff --git a/crates/neon/src/types_impl/extract/try_into_js.rs b/crates/neon/src/types_impl/extract/try_into_js.rs index 126f9fde7..9f452684d 100644 --- a/crates/neon/src/types_impl/extract/try_into_js.rs +++ b/crates/neon/src/types_impl/extract/try_into_js.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use crate::{ context::{Context, Cx}, handle::Handle, @@ -63,6 +65,29 @@ where } } +impl<'cx, T> TryIntoJs<'cx> for Box +where + T: TryIntoJs<'cx>, +{ + type Value = T::Value; + + fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> { + (*self).try_into_js(cx) + } +} + +impl<'cx, T, V> TryIntoJs<'cx> for Arc +where + for<'a> &'a T: TryIntoJs<'cx, Value = V>, + V: Value, +{ + type Value = V; + + fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> { + self.as_ref().try_into_js(cx) + } +} + macro_rules! impl_number { ($ty:ident) => { impl<'cx> TryIntoJs<'cx> for $ty { @@ -91,7 +116,15 @@ impl<'cx> TryIntoJs<'cx> for String { } } -impl<'cx> TryIntoJs<'cx> for &'cx str { +impl<'a, 'cx> TryIntoJs<'cx> for &'a str { + type Value = JsString; + + fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> { + Ok(cx.string(self)) + } +} + +impl<'a, 'cx> TryIntoJs<'cx> for &'a String { type Value = JsString; fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> { @@ -111,7 +144,43 @@ where } } -impl<'cx, T> TryIntoJs<'cx> for &'cx [T] +impl<'cx, T> TryIntoJs<'cx> for Box<[T]> +where + JsTypedArray: Value, + T: Binary, +{ + type Value = JsTypedArray; + + fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> { + JsTypedArray::from_slice(cx, &self) + } +} + +impl<'cx, T, const N: usize> TryIntoJs<'cx> for [T; N] +where + JsTypedArray: Value, + T: Binary, +{ + type Value = JsTypedArray; + + fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> { + JsTypedArray::from_slice(cx, self.as_slice()) + } +} + +impl<'a, 'cx, T> TryIntoJs<'cx> for &'a Vec +where + JsTypedArray: Value, + T: Binary, +{ + type Value = JsTypedArray; + + fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> { + JsTypedArray::from_slice(cx, self) + } +} + +impl<'a, 'cx, T> TryIntoJs<'cx> for &'a [T] where JsTypedArray: Value, T: Binary,