From 841c94541cd7d82b3d62c2c15e9936a33f131f37 Mon Sep 17 00:00:00 2001 From: Alexandr Romanenko Date: Sun, 15 Jun 2025 10:23:27 +0200 Subject: [PATCH 1/5] chore(tesseract): Native utils refactoring --- .../src/wrappers/object_handler.rs | 83 ------------------- .../src/planner/filter/base_filter.rs | 1 + 2 files changed, 1 insertion(+), 83 deletions(-) delete mode 100644 rust/cubenativeutils/src/wrappers/object_handler.rs diff --git a/rust/cubenativeutils/src/wrappers/object_handler.rs b/rust/cubenativeutils/src/wrappers/object_handler.rs deleted file mode 100644 index 65298226ef2d4..0000000000000 --- a/rust/cubenativeutils/src/wrappers/object_handler.rs +++ /dev/null @@ -1,83 +0,0 @@ -use super::context::NativeContextHolder; -use super::object::{ - NativeArray, NativeBoolean, NativeNumber, NativeObject, NativeString, NativeStruct, -}; -use cubesql::CubeError; - -pub struct NativeObjectHandler { - object: Box, -} - -impl NativeObjectHandler { - pub fn new(object: Box) -> Self { - Self { object } - } - - pub fn object_ref(&self) -> &Box { - &self.object - } - - pub fn downcast_object_ref(&self) -> Option<&T> { - self.object.as_any().downcast_ref() - } - - pub fn into_object(self) -> Box { - self.object - } - - pub fn downcast_object(self) -> Result, CubeError> { - self.object - .into_any() - .downcast::() - .map_err(|_| CubeError::internal("Unable to downcast object".to_string())) - } - - pub fn into_struct(self) -> Result, CubeError> { - self.object.into_struct() - } - pub fn into_array(self) -> Result, CubeError> { - self.object.into_array() - } - pub fn into_string(self) -> Result, CubeError> { - self.object.into_string() - } - pub fn into_number(self) -> Result, CubeError> { - self.object.into_number() - } - pub fn into_boolean(self) -> Result, CubeError> { - self.object.into_boolean() - } - pub fn to_struct(&self) -> Result, CubeError> { - self.object.boxed_clone().into_struct() - } - pub fn to_array(&self) -> Result, CubeError> { - self.object.boxed_clone().into_array() - } - pub fn to_string(&self) -> Result, CubeError> { - self.object.boxed_clone().into_string() - } - pub fn to_number(&self) -> Result, CubeError> { - self.object.boxed_clone().into_number() - } - pub fn to_boolean(&self) -> Result, CubeError> { - self.object.boxed_clone().into_boolean() - } - pub fn is_null(&self) -> bool { - self.object.is_null() - } - pub fn is_undefined(&self) -> bool { - self.object.is_undefined() - } - - pub fn get_context(&self) -> Result { - self.object.get_context() - } -} - -impl Clone for NativeObjectHandler { - fn clone(&self) -> Self { - Self { - object: self.object.boxed_clone(), - } - } -} diff --git a/rust/cubesqlplanner/cubesqlplanner/src/planner/filter/base_filter.rs b/rust/cubesqlplanner/cubesqlplanner/src/planner/filter/base_filter.rs index a54dae7dc1f64..bf3c56c7e824c 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/planner/filter/base_filter.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/planner/filter/base_filter.rs @@ -808,6 +808,7 @@ impl BaseFilter { fn is_need_null_chek(&self, is_not: bool) -> bool { let contains_null = self.is_values_contains_null(); + if is_not { !contains_null } else { From a1011c39e810020eecd6dc6e664942872f4e664f Mon Sep 17 00:00:00 2001 From: Alexandr Romanenko Date: Tue, 17 Jun 2025 16:46:28 +0200 Subject: [PATCH 2/5] in work --- .../src/wrappers/neon/object/mod.rs | 22 +-- .../src/wrappers/neon/object/neon_object.rs | 23 +++ .../neon/object/object_root_holder.rs | 66 +++++++ .../neon/object/primitive_root_holder.rs | 174 ++++++++++++++++++ .../src/wrappers/neon/object/root_holder.rs | 106 +++++++++++ 5 files changed, 378 insertions(+), 13 deletions(-) create mode 100644 rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs create mode 100644 rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs create mode 100644 rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs create mode 100644 rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs diff --git a/rust/cubenativeutils/src/wrappers/neon/object/mod.rs b/rust/cubenativeutils/src/wrappers/neon/object/mod.rs index 4f404bec2866a..3c34a5d9bc28d 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/mod.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/mod.rs @@ -1,7 +1,16 @@ pub mod base_types; pub mod neon_array; pub mod neon_function; +pub mod neon_object; pub mod neon_struct; +pub mod object_root_holder; +pub mod primitive_root_holder; +pub mod root_holder; + +use neon_object::*; +use object_root_holder::*; +use primitive_root_holder::*; +use root_holder::*; use self::{ base_types::{NeonBoolean, NeonNumber, NeonString}, @@ -54,19 +63,6 @@ impl + 'static, V: Value + 'static> NeonTypeHandle { self.context.with_context(|cx| f(cx, &self.object)) } - pub fn map_downcast_neon_object(&self, f: F) -> Result - where - F: FnOnce(&mut C, &Handle<'static, JT>) -> Result, - { - self.context.with_context(|cx| { - let obj = self - .object - .downcast::(cx) - .map_err(|_| CubeError::internal("Downcast error".to_string()))?; - f(cx, &obj) - })? - } - pub fn map_neon_object_with_safe_call_fn(&self, f: F) -> Result where F: FnOnce(&mut C, &Handle<'static, V>, SafeCallFn) -> T, diff --git a/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs b/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs new file mode 100644 index 0000000000000..d6f306c624781 --- /dev/null +++ b/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs @@ -0,0 +1,23 @@ +use super::RootHolder; +use crate::wrappers::neon::context::{ContextHolder, SafeCallFn}; +use cubesql::CubeError; +use neon::prelude::*; +use std::rc::Rc; + +pub struct NeonObject + 'static> { + root_holder: RootHolder, +} + +impl + 'static> NeonObject { + pub fn new( + context: ContextHolder, + object: Handle<'static, JsValue>, + ) -> Result { + let root_holder = RootHolder::new(context.clone(), object)?; + Ok(Self { root_holder }) + } + + pub fn form_root(root: RootHolder) -> Self { + Self { root_holder: root } + } +} diff --git a/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs new file mode 100644 index 0000000000000..5d49838a41822 --- /dev/null +++ b/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs @@ -0,0 +1,66 @@ +use crate::wrappers::neon::context::{ContextHolder, SafeCallFn}; +use cubesql::CubeError; +use neon::prelude::*; +use std::mem::MaybeUninit; +use std::rc::Rc; + +#[derive(Clone)] +pub struct ObjectNeonTypeHolder, V: Object + 'static> { + context: ContextHolder, + value: Option>>, +} +impl + 'static, V: Object + 'static> ObjectNeonTypeHolder { + pub fn new(context: ContextHolder, object: Handle<'static, V>) -> Result { + let value = context.with_context(|cx| object.root(cx))?; + Ok(Self { + context, + value: Some(Rc::new(value)), + }) + } + + fn get_context(&self) -> ContextHolder { + self.context.clone() + } + + fn value_ref(&self) -> &Root { + // Invariant: `self.value` must always be `Some` between construction and `Drop`. + // If it's `None` here, it means the object is in an invalid state (e.g. accessed during destruction), + // which is a bug. `unwrap()` is used to enforce this contract by panicking early. + self.value.as_ref().unwrap() + } + + pub fn map_neon_object(&self, f: F) -> Result + where + F: FnOnce(&mut C, &Handle<'static, V>) -> T, + { + self.context.with_context(|cx| { + let object = self.value_ref().to_inner(cx); + f(cx, &object) + }) + } + + pub fn map_neon_object_with_safe_call_fn(&self, f: F) -> Result + where + F: FnOnce(&mut C, &Handle<'static, V>, SafeCallFn) -> T, + { + self.context.with_context_and_safe_fn(|cx, safe_call_fn| { + let object = self.value_ref().to_inner(cx); + f(cx, &object, safe_call_fn) + }) + } +} + +impl, V: Object + 'static> Drop for ObjectNeonTypeHolder { + fn drop(&mut self) { + if let Some(value) = self.value.take() { + if let Ok(value) = Rc::try_unwrap(value) { + let res = self.context.with_context(|cx| { + value.drop(cx); + }); + if let Err(e) = res { + log::error!("Error while dropping Neon Root: {}", e) + } + } + } + } +} diff --git a/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs new file mode 100644 index 0000000000000..6a3c6b6e9d74c --- /dev/null +++ b/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs @@ -0,0 +1,174 @@ +use crate::wrappers::neon::context::{ContextHolder, SafeCallFn}; +use cubesql::CubeError; +use neon::prelude::*; +use std::rc::Rc; + +pub trait NeonPrimitiveMapping: Value { + type NativeType: Clone; + fn from_neon + 'static>( + cx: &mut C, + value: &Handle<'static, Self>, + ) -> Self::NativeType; + fn to_neon + 'static>( + cx: &mut C, + value: &Self::NativeType, + ) -> Handle<'static, Self>; + + fn is_null(&self) -> bool { + false + } + fn is_undefined(&self) -> bool { + false + } +} + +impl NeonPrimitiveMapping for JsBoolean { + type NativeType = bool; + fn from_neon + 'static>( + cx: &mut C, + value: &Handle<'static, Self>, + ) -> Self::NativeType { + value.value(cx) + } + + fn to_neon + 'static>( + cx: &mut C, + value: &Self::NativeType, + ) -> Handle<'static, Self> { + cx.boolean(value.clone()) + } +} + +impl NeonPrimitiveMapping for JsNumber { + type NativeType = f64; + fn from_neon + 'static>( + cx: &mut C, + value: &Handle<'static, Self>, + ) -> Self::NativeType { + value.value(cx) + } + fn to_neon + 'static>( + cx: &mut C, + value: &Self::NativeType, + ) -> Handle<'static, Self> { + cx.number(value.clone()) + } +} + +impl NeonPrimitiveMapping for JsString { + type NativeType = String; + fn from_neon + 'static>( + cx: &mut C, + value: &Handle<'static, Self>, + ) -> Self::NativeType { + value.value(cx) + } + fn to_neon + 'static>( + cx: &mut C, + value: &Self::NativeType, + ) -> Handle<'static, Self> { + cx.string(value) + } +} + +impl NeonPrimitiveMapping for JsNull { + type NativeType = (); + fn from_neon + 'static>( + _cx: &mut C, + _value: &Handle<'static, Self>, + ) -> Self::NativeType { + } + fn to_neon + 'static>( + cx: &mut C, + _value: &Self::NativeType, + ) -> Handle<'static, Self> { + cx.null() + } + + fn is_null(&self) -> bool { + true + } +} + +impl NeonPrimitiveMapping for JsUndefined { + type NativeType = (); + fn from_neon + 'static>( + _cx: &mut C, + _value: &Handle<'static, Self>, + ) -> Self::NativeType { + } + fn to_neon + 'static>( + cx: &mut C, + _value: &Self::NativeType, + ) -> Handle<'static, Self> { + cx.undefined() + } + fn is_undefined(&self) -> bool { + false + } +} + +pub struct PrimitiveNeonTypeHolder, V: NeonPrimitiveMapping + 'static> { + context: ContextHolder, + value: V::NativeType, +} + +impl + 'static, V: Value + NeonPrimitiveMapping + 'static> + PrimitiveNeonTypeHolder +{ + pub fn new(context: ContextHolder, object: Handle<'static, V>) -> Result { + let value = context.with_context(|cx| V::from_neon(cx, &object))?; + Ok(Self { context, value }) + } + + fn get_context(&self) -> ContextHolder { + self.context.clone() + } + + pub fn map_neon_object(&self, f: F) -> Result + where + F: FnOnce(&mut C, &Handle<'static, V>) -> T, + { + self.context.with_context(|cx| { + let object = V::to_neon(cx, &self.value); + f(cx, &object) + }) + } + + pub fn map_neon_object_with_safe_call_fn(&self, f: F) -> Result + where + F: FnOnce(&mut C, &Handle<'static, V>, SafeCallFn) -> T, + { + self.context.with_context_and_safe_fn(|cx, safe_call_fn| { + let object = V::to_neon(cx, &self.value); + f(cx, &object, safe_call_fn) + }) + } + + pub fn into_object(self) -> Result, CubeError> { + self.context.with_context(|cx| V::to_neon(cx, &self.value)) + } + + /* pub fn upcast(&self) -> NeonObject { + NeonObject::new(self.context.clone(), self.object.upcast()) + } + + pub fn map_neon_object(&self, f: F) -> Result + where + F: FnOnce(&mut C, &Handle<'static, V>) -> T, + { + self.context.with_context(|cx| f(cx, &self.object)) + } + + pub fn map_neon_object_with_safe_call_fn(&self, f: F) -> Result + where + F: FnOnce(&mut C, &Handle<'static, V>, SafeCallFn) -> T, + { + self.context + .with_context_and_safe_fn(|cx, safe_call_fn| f(cx, &self.object, safe_call_fn)) + } + + pub fn is_a(&self) -> Result { + self.context.with_context(|cx| self.object.is_a::(cx)) + } */ +} diff --git a/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs new file mode 100644 index 0000000000000..c52f6c703fddf --- /dev/null +++ b/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs @@ -0,0 +1,106 @@ +use super::{ObjectNeonTypeHolder, PrimitiveNeonTypeHolder}; +use crate::wrappers::neon::context::ContextHolder; +use cubesql::CubeError; +use neon::prelude::*; +pub trait Upcast + 'static> { + fn upcast(self) -> RootHolder; +} + +macro_rules! impl_upcast { + ($($holder:ty => $variant:ident),+ $(,)?) => { + $( + impl + 'static> Upcast for $holder { + fn upcast(self) -> RootHolder { + RootHolder::$variant(self) + } + } + )+ + }; +} + +macro_rules! match_js_value_type { + ($context:expr, $value:expr, $cx:expr, { + $($variant:ident => $js_type:ty => $holder_type:ident),+ $(,)? + }) => { + $( + if $value.is_a::<$js_type, _>($cx) { + return Ok(RootHolder::$variant($holder_type::new( + $context.clone(), + $value + .downcast::<$js_type, _>($cx) + .map_err(|_| CubeError::internal("Downcast error".to_string()))?, + )?)); + } + )+ + }; +} + +macro_rules! define_into_method { + ($method_name:ident, $variant:ident, $holder_type:ty, $error_msg:expr) => { + pub fn $method_name(self) -> Result<$holder_type, CubeError> { + match self { + Self::$variant(v) => Ok(v), + _ => Err(CubeError::internal($error_msg.to_string())), + } + } + }; +} + +impl_upcast!( + PrimitiveNeonTypeHolder => Null, + PrimitiveNeonTypeHolder => Undefined, + PrimitiveNeonTypeHolder => Boolean, + PrimitiveNeonTypeHolder => Number, + PrimitiveNeonTypeHolder => String, + ObjectNeonTypeHolder => Array, + ObjectNeonTypeHolder => Function, + ObjectNeonTypeHolder => Struct, +); + +pub enum RootHolder + 'static> { + Null(PrimitiveNeonTypeHolder), + Undefined(PrimitiveNeonTypeHolder), + Boolean(PrimitiveNeonTypeHolder), + Number(PrimitiveNeonTypeHolder), + String(PrimitiveNeonTypeHolder), + Array(ObjectNeonTypeHolder), + Function(ObjectNeonTypeHolder), + Struct(ObjectNeonTypeHolder), +} + +impl + 'static> RootHolder { + pub fn new( + context: ContextHolder, + value: Handle<'static, JsValue>, + ) -> Result { + context.with_context(|cx| { + match_js_value_type!(context, value, cx, { + Null => JsNull => PrimitiveNeonTypeHolder, + Undefined => JsUndefined => PrimitiveNeonTypeHolder, + Boolean => JsBoolean => PrimitiveNeonTypeHolder, + Number => JsNumber => PrimitiveNeonTypeHolder, + String => JsString => PrimitiveNeonTypeHolder, + Array => JsArray => ObjectNeonTypeHolder, + Function => JsFunction => ObjectNeonTypeHolder, + Struct => JsObject => ObjectNeonTypeHolder, + }); + + Err(CubeError::internal(format!( + "Unsupported JsValue {:?}", + value + ))) + })? + } + pub fn from_typed>(typed_holder: T) -> Self { + T::upcast(typed_holder) + } + + define_into_method!(into_null, Null, PrimitiveNeonTypeHolder, "Object is not the Null object"); + define_into_method!(into_undefined, Undefined, PrimitiveNeonTypeHolder, "Object is not the Undefined object"); + define_into_method!(into_boolean, Boolean, PrimitiveNeonTypeHolder, "Object is not the Boolean object"); + define_into_method!(into_number, Number, PrimitiveNeonTypeHolder, "Object is not the Number object"); + define_into_method!(into_string, String, PrimitiveNeonTypeHolder, "Object is not the String object"); + define_into_method!(into_array, Array, ObjectNeonTypeHolder, "Object is not the Array object"); + define_into_method!(into_function, Function, ObjectNeonTypeHolder, "Object is not the Function object"); + define_into_method!(into_struct, Struct, ObjectNeonTypeHolder, "Object is not the Struct object"); +} From 313f19db7de9b7c9cc1c6043419c3c13ada6a76f Mon Sep 17 00:00:00 2001 From: Alexandr Romanenko Date: Tue, 17 Jun 2025 18:46:22 +0200 Subject: [PATCH 3/5] in work --- .../src/wrappers/neon/object/base_types.rs | 1 + .../src/wrappers/neon/object/neon_object.rs | 40 +++++++++++++++++++ .../neon/object/object_root_holder.rs | 2 +- .../neon/object/primitive_root_holder.rs | 2 +- .../src/wrappers/neon/object/root_holder.rs | 13 ++++++ 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/rust/cubenativeutils/src/wrappers/neon/object/base_types.rs b/rust/cubenativeutils/src/wrappers/neon/object/base_types.rs index 2889f970875a5..6d0aab6401f6c 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/base_types.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/base_types.rs @@ -1,4 +1,5 @@ use super::{NeonObject, NeonTypeHandle}; +use super::primitive_root_holder::*; use crate::wrappers::neon::inner_types::NeonInnerTypes; use std::marker::PhantomData; diff --git a/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs b/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs index d6f306c624781..953f559b68fbb 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs @@ -1,5 +1,6 @@ use super::RootHolder; use crate::wrappers::neon::context::{ContextHolder, SafeCallFn}; +use crate::wrappers::object::NativeObject; use cubesql::CubeError; use neon::prelude::*; use std::rc::Rc; @@ -21,3 +22,42 @@ impl + 'static> NeonObject { Self { root_holder: root } } } + +/* impl + 'static> NativeObject> for NeonObject { + fn get_context(&self) -> ContextHolder { + self.root_holder.ge.clone() + } + + fn into_struct(self) -> Result, CubeError> { + let obj = self.downcast_with_err_msg::("NeonObject is not the JsObject")?; + Ok(NeonStruct::new(obj)) + } + fn into_function(self) -> Result, CubeError> { + let obj = self.downcast_with_err_msg::("NeonObject is not the JsArray")?; + Ok(NeonFunction::new(obj)) + } + fn into_array(self) -> Result, CubeError> { + let obj = self.downcast_with_err_msg::("NeonObject is not the JsArray")?; + Ok(NeonArray::new(obj)) + } + fn into_string(self) -> Result, CubeError> { + let obj = self.downcast_with_err_msg::("NeonObject is not the JsString")?; + Ok(NeonString::new(obj)) + } + fn into_number(self) -> Result, CubeError> { + let obj = self.downcast_with_err_msg::("NeonObject is not the JsNumber")?; + Ok(NeonNumber::new(obj)) + } + fn into_boolean(self) -> Result, CubeError> { + let obj = self.downcast_with_err_msg::("NeonObject is not the JsBoolean")?; + Ok(NeonBoolean::new(obj)) + } + + fn is_null(&self) -> Result { + self.is_a::() + } + + fn is_undefined(&self) -> Result { + self.is_a::() + } +} */ diff --git a/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs index 5d49838a41822..29f9bc1775d25 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs @@ -18,7 +18,7 @@ impl + 'static, V: Object + 'static> ObjectNeonTypeHolder ContextHolder { + pub fn get_context(&self) -> ContextHolder { self.context.clone() } diff --git a/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs index 6a3c6b6e9d74c..3f89908444484 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs @@ -121,7 +121,7 @@ impl + 'static, V: Value + NeonPrimitiveMapping + 'static> Ok(Self { context, value }) } - fn get_context(&self) -> ContextHolder { + pub fn get_context(&self) -> ContextHolder { self.context.clone() } diff --git a/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs index c52f6c703fddf..8708613b8feda 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs @@ -95,6 +95,19 @@ impl + 'static> RootHolder { T::upcast(typed_holder) } + pub fn get_context(&self) -> ContextHolder { + match self { + Self::Null(v) => v.get_context(), + Self::Undefined(v) => v.get_context(), + Self::Boolean(v) => v.get_context(), + Self::Number(v) => v.get_context(), + Self::String(v) => v.get_context(), + Self::Array(v) => v.get_context(), + Self::Function(v) => v.get_context(), + Self::Struct(v) => v.get_context(), + } + } + define_into_method!(into_null, Null, PrimitiveNeonTypeHolder, "Object is not the Null object"); define_into_method!(into_undefined, Undefined, PrimitiveNeonTypeHolder, "Object is not the Undefined object"); define_into_method!(into_boolean, Boolean, PrimitiveNeonTypeHolder, "Object is not the Boolean object"); From 4a1200228565bbc56b7088b1febd6cc36452b2e7 Mon Sep 17 00:00:00 2001 From: Alexandr Romanenko Date: Tue, 17 Jun 2025 22:12:16 +0200 Subject: [PATCH 4/5] in work --- .../cubejs-backend-native/src/node_export.rs | 10 +- .../src/wrappers/neon/context.rs | 16 +- .../src/wrappers/neon/object/base_types.rs | 43 ++--- .../src/wrappers/neon/object/mod.rs | 171 +----------------- .../src/wrappers/neon/object/neon_array.rs | 30 ++- .../src/wrappers/neon/object/neon_function.rs | 24 ++- .../src/wrappers/neon/object/neon_object.rs | 84 +++++++-- .../src/wrappers/neon/object/neon_struct.rs | 36 ++-- .../neon/object/object_root_holder.rs | 23 ++- .../neon/object/primitive_root_holder.rs | 41 ++--- .../src/wrappers/neon/object/root_holder.rs | 27 ++- 11 files changed, 214 insertions(+), 291 deletions(-) diff --git a/packages/cubejs-backend-native/src/node_export.rs b/packages/cubejs-backend-native/src/node_export.rs index efe7446537d56..e511c42609141 100644 --- a/packages/cubejs-backend-native/src/node_export.rs +++ b/packages/cubejs-backend-native/src/node_export.rs @@ -577,13 +577,15 @@ pub fn reset_logger(mut cx: FunctionContext) -> JsResult { fn build_sql_and_params(cx: FunctionContext) -> JsResult { neon_run_with_guarded_lifetime(cx, |neon_context_holder| { - let options = - NativeObjectHandle::>>::new(NeonObject::new( + let options = NativeObjectHandle::>>::new( + NeonObject::new( neon_context_holder.clone(), neon_context_holder .with_context(|cx| cx.argument::(0)) .unwrap()?, - )); + ) + .unwrap(), + ); let safe_call_fn = neon_context_holder .with_context(|cx| { @@ -608,7 +610,7 @@ fn build_sql_and_params(cx: FunctionContext) -> JsResult { let res = base_query.build_sql_and_params(); let result: NeonObject> = res.into_object(); - let result = result.into_object(); + let result = result.get_object().unwrap(); Ok(result) }) } diff --git a/rust/cubenativeutils/src/wrappers/neon/context.rs b/rust/cubenativeutils/src/wrappers/neon/context.rs index 637fd30a56564..f133090dd9928 100644 --- a/rust/cubenativeutils/src/wrappers/neon/context.rs +++ b/rust/cubenativeutils/src/wrappers/neon/context.rs @@ -229,17 +229,17 @@ impl + 'static> NativeContext> for Context let obj = NeonObject::new( self.clone(), self.with_context(|cx| cx.boolean(v).upcast())?, - ); + )?; obj.into_boolean() } fn string(&self, v: String) -> Result, CubeError> { - let obj = NeonObject::new(self.clone(), self.with_context(|cx| cx.string(v).upcast())?); + let obj = NeonObject::new(self.clone(), self.with_context(|cx| cx.string(v).upcast())?)?; obj.into_string() } fn number(&self, v: f64) -> Result, CubeError> { - let obj = NeonObject::new(self.clone(), self.with_context(|cx| cx.number(v).upcast())?); + let obj = NeonObject::new(self.clone(), self.with_context(|cx| cx.number(v).upcast())?)?; obj.into_number() } @@ -247,21 +247,21 @@ impl + 'static> NativeContext> for Context Ok(NativeObjectHandle::new(NeonObject::new( self.clone(), self.with_context(|cx| cx.undefined().upcast())?, - ))) + )?)) } fn null(&self) -> Result>, CubeError> { Ok(NativeObjectHandle::new(NeonObject::new( self.clone(), self.with_context(|cx| cx.null().upcast())?, - ))) + )?)) } fn empty_array(&self) -> Result, CubeError> { let obj = NeonObject::new( self.clone(), self.with_context(|cx| cx.empty_array().upcast())?, - ); + )?; obj.into_array() } @@ -269,7 +269,7 @@ impl + 'static> NativeContext> for Context let obj = NeonObject::new( self.clone(), self.with_context(|cx| cx.empty_object().upcast())?, - ); + )?; obj.into_struct() } fn to_string_fn(&self, result: String) -> Result, CubeError> { @@ -280,7 +280,7 @@ impl + 'static> NativeContext> for Context .unwrap() .upcast() })?, - ); + )?; obj.into_function() } } diff --git a/rust/cubenativeutils/src/wrappers/neon/object/base_types.rs b/rust/cubenativeutils/src/wrappers/neon/object/base_types.rs index 6d0aab6401f6c..8019c25034aff 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/base_types.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/base_types.rs @@ -1,83 +1,84 @@ -use super::{NeonObject, NeonTypeHandle}; use super::primitive_root_holder::*; +use super::{NeonObject, RootHolder}; use crate::wrappers::neon::inner_types::NeonInnerTypes; -use std::marker::PhantomData; -use crate::wrappers::object::{NativeBoolean, NativeBox, NativeNumber, NativeString, NativeType}; +use crate::wrappers::object::{NativeBoolean, NativeNumber, NativeString, NativeType}; use cubesql::CubeError; use neon::prelude::*; -use std::ops::Deref; pub struct NeonString> { - object: NeonTypeHandle, + holder: PrimitiveNeonTypeHolder, } impl> NeonString { - pub fn new(object: NeonTypeHandle) -> Self { - Self { object } + pub fn new(holder: PrimitiveNeonTypeHolder) -> Self { + Self { holder } } } impl + 'static> NativeType> for NeonString { fn into_object(self) -> NeonObject { - self.object.upcast() + let root_holder = RootHolder::from_typed(self.holder); + NeonObject::form_root(root_holder) } } impl + 'static> NativeString> for NeonString { fn value(&self) -> Result { - self.object + self.holder .map_neon_object::<_, _>(|cx, object| Ok(object.value(cx)))? } } pub struct NeonNumber> { - object: NeonTypeHandle, + holder: PrimitiveNeonTypeHolder, } impl> NeonNumber { - pub fn new(object: NeonTypeHandle) -> Self { - Self { object } + pub fn new(holder: PrimitiveNeonTypeHolder) -> Self { + Self { holder } } } impl + 'static> NativeType> for NeonNumber { fn into_object(self) -> NeonObject { - self.object.upcast() + let root_holder = RootHolder::from_typed(self.holder); + NeonObject::form_root(root_holder) } } impl + 'static> NativeNumber> for NeonNumber { fn value(&self) -> Result { - self.object + self.holder .map_neon_object::<_, _>(|cx, object| Ok(object.value(cx)))? } } pub struct NeonBoolean> { - object: NeonTypeHandle, + holder: PrimitiveNeonTypeHolder, } impl> NeonBoolean { - pub fn new(object: NeonTypeHandle) -> Self { - Self { object } + pub fn new(holder: PrimitiveNeonTypeHolder) -> Self { + Self { holder } } } impl + 'static> NativeType> for NeonBoolean { fn into_object(self) -> NeonObject { - self.object.upcast() + let root_holder = RootHolder::from_typed(self.holder); + NeonObject::form_root(root_holder) } } impl + 'static> NativeBoolean> for NeonBoolean { fn value(&self) -> Result { - self.object + self.holder .map_neon_object::<_, _>(|cx, object| Ok(object.value(cx)))? } } -pub struct NeonBox, T: 'static> { +/* pub struct NeonBox, T: 'static> { object: NeonTypeHandle>, _marker: PhantomData, } @@ -101,4 +102,4 @@ impl + 'static, T: 'static> NativeBox, T> fn deref_value(&self) -> &T { self.object.get_object_ref().deref() } -} +} */ diff --git a/rust/cubenativeutils/src/wrappers/neon/object/mod.rs b/rust/cubenativeutils/src/wrappers/neon/object/mod.rs index 3c34a5d9bc28d..f3fdd636a2064 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/mod.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/mod.rs @@ -7,176 +7,7 @@ pub mod object_root_holder; pub mod primitive_root_holder; pub mod root_holder; -use neon_object::*; +pub use neon_object::*; use object_root_holder::*; use primitive_root_holder::*; use root_holder::*; - -use self::{ - base_types::{NeonBoolean, NeonNumber, NeonString}, - neon_array::NeonArray, - neon_function::NeonFunction, - neon_struct::NeonStruct, -}; -use super::inner_types::NeonInnerTypes; -use crate::wrappers::{ - neon::context::{ContextHolder, SafeCallFn}, - object::NativeObject, -}; -use cubesql::CubeError; -use neon::prelude::*; - -pub struct NeonTypeHandle, V: Value + 'static> { - context: ContextHolder, - object: Handle<'static, V>, -} - -impl + 'static, V: Value + 'static> NeonTypeHandle { - pub fn new(context: ContextHolder, object: Handle<'static, V>) -> Self { - Self { context, object } - } - - fn get_context(&self) -> ContextHolder { - self.context.clone() - } - - pub fn get_object(&self) -> Handle<'static, V> { - self.object - } - - pub fn get_object_ref(&self) -> &Handle<'static, V> { - &self.object - } - - pub fn into_object(self) -> Handle<'static, V> { - self.object - } - - pub fn upcast(&self) -> NeonObject { - NeonObject::new(self.context.clone(), self.object.upcast()) - } - - pub fn map_neon_object(&self, f: F) -> Result - where - F: FnOnce(&mut C, &Handle<'static, V>) -> T, - { - self.context.with_context(|cx| f(cx, &self.object)) - } - - pub fn map_neon_object_with_safe_call_fn(&self, f: F) -> Result - where - F: FnOnce(&mut C, &Handle<'static, V>, SafeCallFn) -> T, - { - self.context - .with_context_and_safe_fn(|cx, safe_call_fn| f(cx, &self.object, safe_call_fn)) - } - - pub fn is_a(&self) -> Result { - self.context.with_context(|cx| self.object.is_a::(cx)) - } -} - -impl, V: Value + 'static> Clone for NeonTypeHandle { - fn clone(&self) -> Self { - Self { - context: self.context.clone(), - object: self.object, - } - } -} - -pub struct NeonObject> { - context: ContextHolder, - object: Handle<'static, JsValue>, -} - -impl + 'static> NeonObject { - pub fn new(context: ContextHolder, object: Handle<'static, JsValue>) -> Self { - Self { context, object } - } - - pub fn get_object(&self) -> Handle<'static, JsValue> { - self.object - } - - pub fn get_object_ref(&self) -> &Handle<'static, JsValue> { - &self.object - } - - pub fn into_object(self) -> Handle<'static, JsValue> { - self.object - } - - pub fn is_a(&self) -> Result { - self.context.with_context(|cx| self.object.is_a::(cx)) - } - - pub fn downcast(&self) -> Result, CubeError> { - let obj = self.context.with_context(|cx| { - self.object - .downcast::(cx) - .map_err(|_| CubeError::internal("Downcast error".to_string())) - })??; - Ok(NeonTypeHandle::new(self.context.clone(), obj)) - } - - pub fn downcast_with_err_msg( - &self, - msg: &str, - ) -> Result, CubeError> { - let obj = self.context.with_context(|cx| { - self.object - .downcast::(cx) - .map_err(|_| CubeError::internal(msg.to_string())) - })??; - Ok(NeonTypeHandle::new(self.context.clone(), obj)) - } -} - -impl + 'static> NativeObject> for NeonObject { - fn get_context(&self) -> ContextHolder { - self.context.clone() - } - - fn into_struct(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsObject")?; - Ok(NeonStruct::new(obj)) - } - fn into_function(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsArray")?; - Ok(NeonFunction::new(obj)) - } - fn into_array(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsArray")?; - Ok(NeonArray::new(obj)) - } - fn into_string(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsString")?; - Ok(NeonString::new(obj)) - } - fn into_number(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsNumber")?; - Ok(NeonNumber::new(obj)) - } - fn into_boolean(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsBoolean")?; - Ok(NeonBoolean::new(obj)) - } - - fn is_null(&self) -> Result { - self.is_a::() - } - - fn is_undefined(&self) -> Result { - self.is_a::() - } -} - -impl> Clone for NeonObject { - fn clone(&self) -> Self { - Self { - context: self.context.clone(), - object: self.object, - } - } -} diff --git a/rust/cubenativeutils/src/wrappers/neon/object/neon_array.rs b/rust/cubenativeutils/src/wrappers/neon/object/neon_array.rs index 08dea2a0c1ee0..510694c5d1d30 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/neon_array.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/neon_array.rs @@ -1,4 +1,4 @@ -use super::{NeonObject, NeonTypeHandle}; +use super::{NeonObject, ObjectNeonTypeHolder, RootHolder}; use crate::wrappers::{ neon::inner_types::NeonInnerTypes, object::{NativeArray, NativeType}, @@ -7,20 +7,28 @@ use crate::wrappers::{ use cubesql::CubeError; use neon::prelude::*; -#[derive(Clone)] pub struct NeonArray> { - object: NeonTypeHandle, + object: ObjectNeonTypeHolder, } impl + 'static> NeonArray { - pub fn new(object: NeonTypeHandle) -> Self { + pub fn new(object: ObjectNeonTypeHolder) -> Self { Self { object } } } +impl> Clone for NeonArray { + fn clone(&self) -> Self { + Self { + object: self.object.clone(), + } + } +} + impl + 'static> NativeType> for NeonArray { fn into_object(self) -> NeonObject { - self.object.upcast() + let root_holder = RootHolder::from_typed(self.object); + NeonObject::form_root(root_holder) } } @@ -36,17 +44,19 @@ impl + 'static> NativeArray> for NeonArray .map_err(|_| CubeError::internal("Error converting JsArray to Vec".to_string())) })??; - Ok(neon_vec + neon_vec .into_iter() - .map(|o| NativeObjectHandle::new(NeonObject::new(self.object.get_context(), o))) - .collect()) + .map(|o| -> Result<_, CubeError> { + Ok(NativeObjectHandle::new(NeonObject::new(self.object.get_context(), o)?)) + }) + .collect::, _>>() } fn set( &self, index: u32, value: NativeObjectHandle>, ) -> Result { - let value = value.into_object().into_object(); + let value = value.into_object().get_object()?; self.object.map_neon_object::<_, _>(|cx, object| { object .set(cx, index, value) @@ -62,6 +72,6 @@ impl + 'static> NativeArray> for NeonArray Ok(NativeObjectHandle::new(NeonObject::new( self.object.get_context(), r, - ))) + )?)) } } diff --git a/rust/cubenativeutils/src/wrappers/neon/object/neon_function.rs b/rust/cubenativeutils/src/wrappers/neon/object/neon_function.rs index 79829631c5cab..511aa46766637 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/neon_function.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/neon_function.rs @@ -1,4 +1,4 @@ -use super::{NeonObject, NeonTypeHandle}; +use super::{NeonObject, RootHolder, ObjectNeonTypeHolder}; use crate::wrappers::{ neon::inner_types::NeonInnerTypes, object::{NativeFunction, NativeType}, @@ -9,20 +9,28 @@ use lazy_static::lazy_static; use neon::prelude::*; use regex::Regex; -#[derive(Clone)] pub struct NeonFunction> { - object: NeonTypeHandle, + object: ObjectNeonTypeHolder, } impl + 'static> NeonFunction { - pub fn new(object: NeonTypeHandle) -> Self { + pub fn new(object: ObjectNeonTypeHolder) -> Self { Self { object } } } +impl> Clone for NeonFunction { + fn clone(&self) -> Self { + Self { + object: self.object.clone(), + } + } +} + impl + 'static> NativeType> for NeonFunction { fn into_object(self) -> NeonObject { - self.object.upcast() + let root_holder = RootHolder::from_typed(self.object); + NeonObject::form_root(root_holder) } } @@ -33,7 +41,7 @@ impl + 'static> NativeFunction> for NeonFu ) -> Result>, CubeError> { let neon_args = args .into_iter() - .map(|arg| -> Result<_, CubeError> { Ok(arg.into_object().get_object()) }) + .map(|arg| -> Result<_, CubeError> { arg.into_object().get_object() }) .collect::, _>>()?; let neon_reuslt = self.object @@ -42,9 +50,9 @@ impl + 'static> NativeFunction> for NeonFu safe_call_fn.safe_call(cx, neon_object, null, neon_args) })??; Ok(NativeObjectHandle::new(NeonObject::new( - self.object.context.clone(), + self.object.get_context(), neon_reuslt, - ))) + )?)) } fn definition(&self) -> Result { diff --git a/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs b/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs index 953f559b68fbb..39e64e8bd9308 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs @@ -1,9 +1,17 @@ -use super::RootHolder; -use crate::wrappers::neon::context::{ContextHolder, SafeCallFn}; +use super::{ + base_types::{NeonBoolean, NeonNumber, NeonString}, + neon_array::NeonArray, + neon_function::NeonFunction, + neon_struct::NeonStruct, + RootHolder, +}; +use crate::wrappers::neon::{ + context::ContextHolder, + inner_types::NeonInnerTypes, +}; use crate::wrappers::object::NativeObject; use cubesql::CubeError; use neon::prelude::*; -use std::rc::Rc; pub struct NeonObject + 'static> { root_holder: RootHolder, @@ -21,43 +29,79 @@ impl + 'static> NeonObject { pub fn form_root(root: RootHolder) -> Self { Self { root_holder: root } } + + pub fn get_object(&self) -> Result, CubeError> { + match &self.root_holder { + RootHolder::Null(v) => v.map_neon_object(|_cx, obj| Ok(obj.upcast())), + RootHolder::Undefined(v) => v.map_neon_object(|_cx, obj| Ok(obj.upcast())), + RootHolder::Boolean(v) => v.map_neon_object(|_cx, obj| Ok(obj.upcast())), + RootHolder::Number(v) => v.map_neon_object(|_cx, obj| Ok(obj.upcast())), + RootHolder::String(v) => v.map_neon_object(|_cx, obj| Ok(obj.upcast())), + RootHolder::Array(v) => v.map_neon_object(|_cx, obj| Ok(obj.upcast())), + RootHolder::Function(v) => v.map_neon_object(|_cx, obj| Ok(obj.upcast())), + RootHolder::Struct(v) => v.map_neon_object(|_cx, obj| Ok(obj.upcast())), + }? + } + + pub fn is_a(&self) -> Result { + let obj = self.get_object()?; + self.root_holder + .get_context() + .with_context(|cx| obj.is_a::(cx)) + } + + pub fn is_null(&self) -> bool { + matches!(self.root_holder, RootHolder::Null(_)) + } + + pub fn is_undefined(&self) -> bool { + matches!(self.root_holder, RootHolder::Undefined(_)) + } } -/* impl + 'static> NativeObject> for NeonObject { +impl + 'static> NativeObject> for NeonObject { fn get_context(&self) -> ContextHolder { - self.root_holder.ge.clone() + self.root_holder.get_context() } fn into_struct(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsObject")?; - Ok(NeonStruct::new(obj)) + let obj_holder = self.root_holder.into_struct()?; + Ok(NeonStruct::new(obj_holder)) } fn into_function(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsArray")?; - Ok(NeonFunction::new(obj)) + let obj_holder = self.root_holder.into_function()?; + Ok(NeonFunction::new(obj_holder)) } fn into_array(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsArray")?; - Ok(NeonArray::new(obj)) + let obj_holder = self.root_holder.into_array()?; + Ok(NeonArray::new(obj_holder)) } fn into_string(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsString")?; - Ok(NeonString::new(obj)) + let holder = self.root_holder.into_string()?; + Ok(NeonString::new(holder)) } fn into_number(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsNumber")?; - Ok(NeonNumber::new(obj)) + let holder = self.root_holder.into_number()?; + Ok(NeonNumber::new(holder)) } fn into_boolean(self) -> Result, CubeError> { - let obj = self.downcast_with_err_msg::("NeonObject is not the JsBoolean")?; - Ok(NeonBoolean::new(obj)) + let holder = self.root_holder.into_boolean()?; + Ok(NeonBoolean::new(holder)) } fn is_null(&self) -> Result { - self.is_a::() + Ok(self.is_null()) } fn is_undefined(&self) -> Result { - self.is_a::() + Ok(self.is_undefined()) + } +} + +impl + 'static> Clone for NeonObject { + fn clone(&self) -> Self { + Self { + root_holder: self.root_holder.clone(), + } } -} */ +} diff --git a/rust/cubenativeutils/src/wrappers/neon/object/neon_struct.rs b/rust/cubenativeutils/src/wrappers/neon/object/neon_struct.rs index 7f835698642fe..6a0bf06d9c523 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/neon_struct.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/neon_struct.rs @@ -1,4 +1,4 @@ -use super::{NeonObject, NeonTypeHandle}; +use super::{NeonObject, ObjectNeonTypeHolder, RootHolder}; use crate::wrappers::{ neon::inner_types::NeonInnerTypes, object::{NativeStruct, NativeType}, @@ -7,20 +7,28 @@ use crate::wrappers::{ use cubesql::CubeError; use neon::prelude::*; -#[derive(Clone)] pub struct NeonStruct> { - object: NeonTypeHandle, + object: ObjectNeonTypeHolder, } impl + 'static> NeonStruct { - pub fn new(object: NeonTypeHandle) -> Self { + pub fn new(object: ObjectNeonTypeHolder) -> Self { Self { object } } } +impl> Clone for NeonStruct { + fn clone(&self) -> Self { + Self { + object: self.object.clone(), + } + } +} + impl + 'static> NativeType> for NeonStruct { fn into_object(self) -> NeonObject { - self.object.upcast() + let root_holder = RootHolder::from_typed(self.object); + NeonObject::form_root(root_holder) } } @@ -35,9 +43,9 @@ impl + 'static> NativeStruct> for NeonStru .map_err(|_| CubeError::internal(format!("Field `{}` not found", field_name))) })??; Ok(NativeObjectHandle::new(NeonObject::new( - self.object.context.clone(), + self.object.get_context(), neon_result, - ))) + )?)) } fn has_field(&self, field_name: &str) -> Result { @@ -63,7 +71,7 @@ impl + 'static> NativeStruct> for NeonStru field_name: &str, value: NativeObjectHandle>, ) -> Result { - let value = value.into_object().into_object(); + let value = value.into_object().get_object()?; self.object.map_neon_object::<_, _>(|cx, object| { object .set(cx, field_name, value) @@ -82,10 +90,10 @@ impl + 'static> NativeStruct> for NeonStru .to_vec(cx) .map_err(|_| CubeError::internal("Failed to convert array".to_string())) })??; - Ok(neon_array + neon_array .into_iter() - .map(|o| NativeObjectHandle::new(NeonObject::new(self.object.context.clone(), o))) - .collect()) + .map(|o| NeonObject::new(self.object.get_context(), o).map(NativeObjectHandle::new)) + .collect::, _>>() } fn call_method( &self, @@ -94,7 +102,7 @@ impl + 'static> NativeStruct> for NeonStru ) -> Result>, CubeError> { let neon_args = args .into_iter() - .map(|arg| -> Result<_, CubeError> { Ok(arg.into_object().get_object()) }) + .map(|arg| -> Result<_, CubeError> { arg.into_object().get_object() }) .collect::, _>>()?; let neon_reuslt = @@ -109,8 +117,8 @@ impl + 'static> NativeStruct> for NeonStru safe_call_fn.safe_call(cx, &neon_method, *neon_object, neon_args) })??; Ok(NativeObjectHandle::new(NeonObject::new( - self.object.context.clone(), + self.object.get_context(), neon_reuslt, - ))) + )?)) } } diff --git a/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs index 29f9bc1775d25..3fa4b676ca3b9 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs @@ -1,21 +1,23 @@ use crate::wrappers::neon::context::{ContextHolder, SafeCallFn}; use cubesql::CubeError; use neon::prelude::*; -use std::mem::MaybeUninit; use std::rc::Rc; -#[derive(Clone)] pub struct ObjectNeonTypeHolder, V: Object + 'static> { context: ContextHolder, value: Option>>, } impl + 'static, V: Object + 'static> ObjectNeonTypeHolder { - pub fn new(context: ContextHolder, object: Handle<'static, V>) -> Result { - let value = context.with_context(|cx| object.root(cx))?; - Ok(Self { + pub fn new( + context: ContextHolder, + object: Handle<'static, V>, + cx: &mut C, + ) -> Self { + let value = object.root(cx); + Self { context, value: Some(Rc::new(value)), - }) + } } pub fn get_context(&self) -> ContextHolder { @@ -64,3 +66,12 @@ impl, V: Object + 'static> Drop for ObjectNeonTypeHolder, V: Object + 'static> Clone for ObjectNeonTypeHolder { + fn clone(&self) -> Self { + Self { + context: self.context.clone(), + value: self.value.clone(), + } + } +} diff --git a/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs index 3f89908444484..e545ee76b826c 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs @@ -1,7 +1,6 @@ use crate::wrappers::neon::context::{ContextHolder, SafeCallFn}; use cubesql::CubeError; use neon::prelude::*; -use std::rc::Rc; pub trait NeonPrimitiveMapping: Value { type NativeType: Clone; @@ -116,9 +115,13 @@ pub struct PrimitiveNeonTypeHolder, V: NeonPrimitiveMapping impl + 'static, V: Value + NeonPrimitiveMapping + 'static> PrimitiveNeonTypeHolder { - pub fn new(context: ContextHolder, object: Handle<'static, V>) -> Result { - let value = context.with_context(|cx| V::from_neon(cx, &object))?; - Ok(Self { context, value }) + pub fn new( + context: ContextHolder, + object: Handle<'static, V>, + cx: &mut C, + ) -> Self { + let value = V::from_neon(cx, &object); + Self { context, value } } pub fn get_context(&self) -> ContextHolder { @@ -148,27 +151,15 @@ impl + 'static, V: Value + NeonPrimitiveMapping + 'static> pub fn into_object(self) -> Result, CubeError> { self.context.with_context(|cx| V::to_neon(cx, &self.value)) } +} - /* pub fn upcast(&self) -> NeonObject { - NeonObject::new(self.context.clone(), self.object.upcast()) - } - - pub fn map_neon_object(&self, f: F) -> Result - where - F: FnOnce(&mut C, &Handle<'static, V>) -> T, - { - self.context.with_context(|cx| f(cx, &self.object)) - } - - pub fn map_neon_object_with_safe_call_fn(&self, f: F) -> Result - where - F: FnOnce(&mut C, &Handle<'static, V>, SafeCallFn) -> T, - { - self.context - .with_context_and_safe_fn(|cx, safe_call_fn| f(cx, &self.object, safe_call_fn)) +impl, V: NeonPrimitiveMapping + 'static> Clone + for PrimitiveNeonTypeHolder +{ + fn clone(&self) -> Self { + Self { + context: self.context.clone(), + value: self.value.clone(), + } } - - pub fn is_a(&self) -> Result { - self.context.with_context(|cx| self.object.is_a::(cx)) - } */ } diff --git a/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs index 8708613b8feda..6105f37a2398a 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/root_holder.rs @@ -20,16 +20,18 @@ macro_rules! impl_upcast { macro_rules! match_js_value_type { ($context:expr, $value:expr, $cx:expr, { - $($variant:ident => $js_type:ty => $holder_type:ident),+ $(,)? + $($variant:ident => $js_type:ty => $holder_type:ident),+ $(,)? }) => { $( if $value.is_a::<$js_type, _>($cx) { + let downcasted = $value + .downcast::<$js_type, _>($cx) + .map_err(|_| CubeError::internal("Downcast error".to_string()))?; return Ok(RootHolder::$variant($holder_type::new( $context.clone(), - $value - .downcast::<$js_type, _>($cx) - .map_err(|_| CubeError::internal("Downcast error".to_string()))?, - )?)); + downcasted, + $cx + ))); } )+ }; @@ -117,3 +119,18 @@ impl + 'static> RootHolder { define_into_method!(into_function, Function, ObjectNeonTypeHolder, "Object is not the Function object"); define_into_method!(into_struct, Struct, ObjectNeonTypeHolder, "Object is not the Struct object"); } + +impl + 'static> Clone for RootHolder { + fn clone(&self) -> Self { + match self { + Self::Null(v) => Self::Null(v.clone()), + Self::Undefined(v) => Self::Undefined(v.clone()), + Self::Boolean(v) => Self::Boolean(v.clone()), + Self::Number(v) => Self::Number(v.clone()), + Self::String(v) => Self::String(v.clone()), + Self::Array(v) => Self::Array(v.clone()), + Self::Function(v) => Self::Function(v.clone()), + Self::Struct(v) => Self::Struct(v.clone()), + } + } +} From 5e0165d76535e245ca62d6cb75596903201451e6 Mon Sep 17 00:00:00 2001 From: Alexandr Romanenko Date: Wed, 18 Jun 2025 17:28:00 +0200 Subject: [PATCH 5/5] lint --- rust/cubenativeutils/src/wrappers/neon/object/neon_array.rs | 5 ++++- .../src/wrappers/neon/object/neon_function.rs | 2 +- .../cubenativeutils/src/wrappers/neon/object/neon_object.rs | 5 +---- .../src/wrappers/neon/object/object_root_holder.rs | 6 +----- .../src/wrappers/neon/object/primitive_root_holder.rs | 6 +----- 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/rust/cubenativeutils/src/wrappers/neon/object/neon_array.rs b/rust/cubenativeutils/src/wrappers/neon/object/neon_array.rs index 510694c5d1d30..fa8d74e105d48 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/neon_array.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/neon_array.rs @@ -47,7 +47,10 @@ impl + 'static> NativeArray> for NeonArray neon_vec .into_iter() .map(|o| -> Result<_, CubeError> { - Ok(NativeObjectHandle::new(NeonObject::new(self.object.get_context(), o)?)) + Ok(NativeObjectHandle::new(NeonObject::new( + self.object.get_context(), + o, + )?)) }) .collect::, _>>() } diff --git a/rust/cubenativeutils/src/wrappers/neon/object/neon_function.rs b/rust/cubenativeutils/src/wrappers/neon/object/neon_function.rs index 511aa46766637..e6adba75c7f55 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/neon_function.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/neon_function.rs @@ -1,4 +1,4 @@ -use super::{NeonObject, RootHolder, ObjectNeonTypeHolder}; +use super::{NeonObject, ObjectNeonTypeHolder, RootHolder}; use crate::wrappers::{ neon::inner_types::NeonInnerTypes, object::{NativeFunction, NativeType}, diff --git a/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs b/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs index 39e64e8bd9308..e0c3cca04aa13 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/neon_object.rs @@ -5,10 +5,7 @@ use super::{ neon_struct::NeonStruct, RootHolder, }; -use crate::wrappers::neon::{ - context::ContextHolder, - inner_types::NeonInnerTypes, -}; +use crate::wrappers::neon::{context::ContextHolder, inner_types::NeonInnerTypes}; use crate::wrappers::object::NativeObject; use cubesql::CubeError; use neon::prelude::*; diff --git a/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs index 3fa4b676ca3b9..2f74b4b43f4e1 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/object_root_holder.rs @@ -8,11 +8,7 @@ pub struct ObjectNeonTypeHolder, V: Object + 'static> { value: Option>>, } impl + 'static, V: Object + 'static> ObjectNeonTypeHolder { - pub fn new( - context: ContextHolder, - object: Handle<'static, V>, - cx: &mut C, - ) -> Self { + pub fn new(context: ContextHolder, object: Handle<'static, V>, cx: &mut C) -> Self { let value = object.root(cx); Self { context, diff --git a/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs b/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs index e545ee76b826c..45f485de08569 100644 --- a/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs +++ b/rust/cubenativeutils/src/wrappers/neon/object/primitive_root_holder.rs @@ -115,11 +115,7 @@ pub struct PrimitiveNeonTypeHolder, V: NeonPrimitiveMapping impl + 'static, V: Value + NeonPrimitiveMapping + 'static> PrimitiveNeonTypeHolder { - pub fn new( - context: ContextHolder, - object: Handle<'static, V>, - cx: &mut C, - ) -> Self { + pub fn new(context: ContextHolder, object: Handle<'static, V>, cx: &mut C) -> Self { let value = V::from_neon(cx, &object); Self { context, value } }