From 5989a79f0d43bc6260b37b1918d0fa2634f6613c Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 10 Dec 2020 14:07:08 +0800 Subject: [PATCH] feat(napi): unsafe cast JsUnknown to the other JsValue --- napi/src/js_values/mod.rs | 11 +++++++++++ test_module/__test__/js-value.spec.ts | 11 +++++++++++ test_module/src/env.rs | 7 +++++++ 3 files changed, 29 insertions(+) diff --git a/napi/src/js_values/mod.rs b/napi/src/js_values/mod.rs index 326d7dd8..a2a9c76e 100644 --- a/napi/src/js_values/mod.rs +++ b/napi/src/js_values/mod.rs @@ -607,4 +607,15 @@ impl JsUnknown { pub fn get_type(&self) -> Result { unsafe { type_of!(self.0.env, self.0.value) } } + + #[inline] + /// # Safety + /// This function should be called after `JsUnknown::get_type` + /// And the `V` must be match with the return value of `get_type` + pub unsafe fn cast(self) -> V + where + V: NapiValue, + { + V::from_raw_unchecked(self.0.env, self.0.value) + } } diff --git a/test_module/__test__/js-value.spec.ts b/test_module/__test__/js-value.spec.ts index 402da262..d5bbf08c 100644 --- a/test_module/__test__/js-value.spec.ts +++ b/test_module/__test__/js-value.spec.ts @@ -47,3 +47,14 @@ test('strict_equals', (t) => { t.false(bindings.strictEquals(NaN, NaN)) t.true(bindings.strictEquals(a, a)) }) + +test('cast_unknown', (t) => { + const f = {} + const r = bindings.castUnknown(f) + t.is(f, r) +}) + +test('cast_unknown will not throw', (t) => { + const f = 1 + t.notThrows(() => bindings.castUnknown(f)) +}) diff --git a/test_module/src/env.rs b/test_module/src/env.rs index 0648a4f8..43dda012 100644 --- a/test_module/src/env.rs +++ b/test_module/src/env.rs @@ -26,10 +26,17 @@ pub fn strict_equals(ctx: CallContext) -> Result { ctx.env.get_boolean(ctx.env.strict_equals(a, b)?) } +#[js_function(1)] +pub fn cast_unknown(ctx: CallContext) -> Result { + let arg: JsUnknown = ctx.get(0)?; + Ok(unsafe { arg.cast::() }) +} + pub fn register_js(exports: &mut JsObject) -> Result<()> { exports.create_named_method("instanceof", instanceof)?; exports.create_named_method("isTypedarray", is_typedarray)?; exports.create_named_method("isDataview", is_dataview)?; exports.create_named_method("strictEquals", strict_equals)?; + exports.create_named_method("castUnknown", cast_unknown)?; Ok(()) }