Skip to content

Commit

Permalink
Merge pull request #1066 from neon-bindings/kv/extract-types
Browse files Browse the repository at this point in the history
feat(neon): Add more TryIntoJs and TryFromJs implementations
  • Loading branch information
kjvalencik authored Sep 20, 2024
2 parents 68c48ef + f6a6e92 commit ffb3f99
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 5 deletions.
36 changes: 34 additions & 2 deletions crates/neon/src/types_impl/extract/private.rs
Original file line number Diff line number Diff line change
@@ -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,
},
};
Expand Down Expand Up @@ -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<O: Object> Sealed for Root<O> {}

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

impl<T, E> Sealed for Result<T, E> {}
Expand All @@ -46,13 +53,38 @@ where
{
}

impl<T> Sealed for Box<[T]>
where
JsTypedArray<T>: Value,
T: Binary,
{
}

impl<T, const N: usize> Sealed for [T; N]
where
JsTypedArray<T>: Value,
T: Binary,
{
}

impl<T> Sealed for &Vec<T>
where
JsTypedArray<T>: Value,
T: Binary,
{
}

impl<T> Sealed for &[T]
where
JsTypedArray<T>: Value,
T: Binary,
{
}

impl<'cx, T> Sealed for Arc<T> where for<'a> &'a T: TryIntoJs<'cx> {}

impl<'cx, T> Sealed for Box<T> where T: TryIntoJs<'cx> {}

impl_sealed!(
u8,
u16,
Expand Down
22 changes: 21 additions & 1 deletion crates/neon/src/types_impl/extract/try_from_js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -45,6 +46,25 @@ where
from_js!();
}

impl<'cx, O> TryFromJs<'cx> for Root<O>
where
O: Object,
{
type Error = TypeExpected<O>;

fn try_from_js(
cx: &mut Cx<'cx>,
v: Handle<'cx, JsValue>,
) -> NeonResult<Result<Self, Self::Error>> {
Ok(match v.downcast::<O, _>(cx) {
Ok(v) => Ok(v.root(cx)),
Err(_) => Err(TypeExpected::new()),
})
}

from_js!();
}

impl<'cx, T> TryFromJs<'cx> for Option<T>
where
T: TryFromJs<'cx>,
Expand Down
73 changes: 71 additions & 2 deletions crates/neon/src/types_impl/extract/try_into_js.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::sync::Arc;

use crate::{
context::{Context, Cx},
handle::Handle,
Expand Down Expand Up @@ -63,6 +65,29 @@ where
}
}

impl<'cx, T> TryIntoJs<'cx> for Box<T>
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<T>
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 {
Expand Down Expand Up @@ -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> {
Expand All @@ -111,7 +144,43 @@ where
}
}

impl<'cx, T> TryIntoJs<'cx> for &'cx [T]
impl<'cx, T> TryIntoJs<'cx> for Box<[T]>
where
JsTypedArray<T>: Value,
T: Binary,
{
type Value = JsTypedArray<T>;

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<T>: Value,
T: Binary,
{
type Value = JsTypedArray<T>;

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<T>
where
JsTypedArray<T>: Value,
T: Binary,
{
type Value = JsTypedArray<T>;

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<T>: Value,
T: Binary,
Expand Down

0 comments on commit ffb3f99

Please sign in to comment.