diff --git a/crates/neon/src/types_impl/extract/private.rs b/crates/neon/src/types_impl/extract/private.rs index 1226ecbee..af3687402 100644 --- a/crates/neon/src/types_impl/extract/private.rs +++ b/crates/neon/src/types_impl/extract/private.rs @@ -1,10 +1,13 @@ +use std::sync::Arc; + use crate::{ context::FunctionContext, - handle::Handle, + handle::{Handle, Root}, + object::Object, result::{NeonResult, Throw}, types::{ buffer::Binary, - extract::{ArrayBuffer, Buffer, Date, Error}, + extract::{ArrayBuffer, Buffer, Date, Error, TryIntoJs}, JsTypedArray, Value, }, }; @@ -33,8 +36,12 @@ impl Sealed for () {} impl Sealed for &str {} +impl Sealed for &String {} + impl<'cx, V: Value> Sealed for Handle<'cx, V> {} +impl Sealed for Root {} + impl Sealed for Option {} impl Sealed for Result {} @@ -46,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, @@ -53,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_from_js.rs b/crates/neon/src/types_impl/extract/try_from_js.rs index c34959408..90724794d 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>, 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,