diff --git a/source/ports/rs_port/src/cast.rs b/source/ports/rs_port/src/cast.rs index 51574fdf1..61e4c3e8c 100644 --- a/source/ports/rs_port/src/cast.rs +++ b/source/ports/rs_port/src/cast.rs @@ -235,6 +235,6 @@ pub fn metacallobj_untyped_to_raw(ret: Box) -> Option<*mut c_ None } -pub fn metacall_implementer_to_traitobj(v: impl MetaCallValue) -> Box { +pub fn metacall_box(v: impl MetaCallValue) -> Box { Box::new(v) as Box } diff --git a/source/ports/rs_port/src/lib.rs b/source/ports/rs_port/src/lib.rs index 0f1f282a0..3c7c9e94d 100644 --- a/source/ports/rs_port/src/lib.rs +++ b/source/ports/rs_port/src/lib.rs @@ -88,6 +88,7 @@ pub use types::*; #[doc(hidden)] mod init; +pub use cast::metacall_box; pub use init::initialize; pub use init::is_initialized; diff --git a/source/ports/rs_port/src/types/metacall_exception.rs b/source/ports/rs_port/src/types/metacall_exception.rs index c3bf662cc..f753fce6c 100644 --- a/source/ports/rs_port/src/types/metacall_exception.rs +++ b/source/ports/rs_port/src/types/metacall_exception.rs @@ -180,7 +180,7 @@ impl MetaCallThrowable { Ok(mut value) => { value.leak = true; - cast::metacall_implementer_to_traitobj(value) + cast::metacall_box(value) } Err(original) => original, } diff --git a/source/ports/rs_port/src/types/metacall_value.rs b/source/ports/rs_port/src/types/metacall_value.rs index 97a669567..bbc5870ff 100644 --- a/source/ports/rs_port/src/types/metacall_value.rs +++ b/source/ports/rs_port/src/types/metacall_value.rs @@ -429,3 +429,36 @@ impl MetaCallValue for MetaCallThrowable { self.into_raw() } } +/// Just a Rust barrier made for easier polymorphism. +impl MetaCallValue for Box { + fn get_metacall_id() -> metacall_value_id { + metacall_value_id::METACALL_INVALID + } + fn from_metacall_raw_leak(v: *mut c_void) -> Result> { + Ok(cast::raw_to_metacallobj_untyped_leak(v)) + } + fn into_metacall_raw(self) -> *mut c_void { + match_metacall_value!(self, { + bool: bool => bool.into_metacall_raw(), + char: char => char.into_metacall_raw(), + num: i16 => num.into_metacall_raw(), + num: i32 => num.into_metacall_raw(), + num: i64 => num.into_metacall_raw(), + num: f32 => num.into_metacall_raw(), + num: f64 => num.into_metacall_raw(), + str: String => str.into_metacall_raw(), + buf: Vec => buf.into_metacall_raw(), + arr: Vec> => arr.into_metacall_raw(), + map: HashMap> => map.into_metacall_raw(), + ptr: MetaCallPointer => ptr.into_metacall_raw(), + fut: MetaCallFuture => fut.into_metacall_raw(), + fun: MetaCallFunction => fun.into_metacall_raw(), + null: MetaCallNull => null.into_metacall_raw(), + cls: MetaCallClass => cls.into_metacall_raw(), + obj: MetaCallObject => obj.into_metacall_raw(), + exc: MetaCallException => exc.into_metacall_raw(), + thr: MetaCallThrowable => thr.into_metacall_raw(), + _ => MetaCallNull().into_metacall_raw() + }) + } +} diff --git a/source/ports/rs_port/tests/metacall_test.rs b/source/ports/rs_port/tests/metacall_test.rs index ad6389262..9963240d8 100644 --- a/source/ports/rs_port/tests/metacall_test.rs +++ b/source/ports/rs_port/tests/metacall_test.rs @@ -81,27 +81,21 @@ fn test_float() { fn test_double() { generate_test::("test_double", 1.2345_f64); } -// TODO -// fn test_mixed_numbers() { -// let result = ::metacall::metacall::( -// "test_mixed_numbers", -// [ -// Box::new(1 as i16) as Box, -// Box::new(2 as i32) as Box, -// Box::new(3 as i64) as Box, -// ], -// ); - -// // TODO -// // ::metacall::metacall::("test_mixed_numbers", [1_i16, 2_i32, 3_i64]); -// // ::metacall::metacall::("test_mixed_numbers", (1_i16, 2_i32, 3_i64)); - -// assert!(result.is_ok()); +fn test_mixed_numbers() { + let result = ::metacall::metacall::( + "test_mixed_numbers", + [ + ::metacall::metacall_box(1 as i16), + ::metacall::metacall_box(2 as i32), + ::metacall::metacall_box(3 as i64), + ], + ); -// if let Ok(ret) = result { -// assert_eq!(ret, 6_i64) -// } -// } + assert!(result.is_ok()); + if let Ok(ret) = result { + assert_eq!(ret, 6_i64) + } +} fn test_string() { generate_test::( "return_the_argument_py", @@ -393,8 +387,7 @@ fn metacall() { test_int(); test_long(); test_short(); - // TODO - // test_mixed_numbers(); + test_mixed_numbers(); } if load::from_single_file("node", js_test_file).is_ok() { test_exception();