From b6d126db53c59399b75040c754c6b147da8eac93 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 6 Jan 2022 16:16:43 +0800 Subject: [PATCH] fix(napi-derive): implement missing trait for JsClass reference --- crates/backend/src/codegen/struct.rs | 50 ++++++++++++++++++++ examples/napi/__test__/typegen.spec.ts.md | 5 ++ examples/napi/__test__/typegen.spec.ts.snap | Bin 2252 -> 2284 bytes examples/napi/__test__/values.spec.ts | 10 ++++ examples/napi/index.d.ts | 5 ++ examples/napi/src/either.rs | 27 +++++++++++ 6 files changed, 97 insertions(+) diff --git a/crates/backend/src/codegen/struct.rs b/crates/backend/src/codegen/struct.rs index 4e1ef477..a3c431c4 100644 --- a/crates/backend/src/codegen/struct.rs +++ b/crates/backend/src/codegen/struct.rs @@ -25,6 +25,26 @@ fn gen_napi_value_map_impl(name: &Ident, to_napi_val_impl: TokenStream) -> Token } } + impl napi::bindgen_prelude::TypeName for &#name { + fn type_name() -> &'static str { + #name_str + } + + fn value_type() -> napi::ValueType { + napi::ValueType::Object + } + } + + impl napi::bindgen_prelude::TypeName for &mut #name { + fn type_name() -> &'static str { + #name_str + } + + fn value_type() -> napi::ValueType { + napi::ValueType::Object + } + } + #to_napi_val_impl impl napi::bindgen_prelude::FromNapiRef for #name { @@ -60,6 +80,36 @@ fn gen_napi_value_map_impl(name: &Ident, to_napi_val_impl: TokenStream) -> Token Ok(&mut *(wrapped_val as *mut #name)) } } + + impl napi::bindgen_prelude::FromNapiValue for &#name { + unsafe fn from_napi_value( + env: napi::bindgen_prelude::sys::napi_env, + napi_val: napi::bindgen_prelude::sys::napi_value + ) -> napi::bindgen_prelude::Result { + napi::bindgen_prelude::FromNapiRef::from_napi_ref(env, napi_val) + } + } + + impl napi::bindgen_prelude::FromNapiValue for &mut #name { + unsafe fn from_napi_value( + env: napi::bindgen_prelude::sys::napi_env, + napi_val: napi::bindgen_prelude::sys::napi_value + ) -> napi::bindgen_prelude::Result { + napi::bindgen_prelude::FromNapiMutRef::from_napi_mut_ref(env, napi_val) + } + } + + impl napi::NapiRaw for &#name { + unsafe fn raw(&self) -> napi::sys::napi_value { + unreachable!() + } + } + + impl napi::NapiRaw for &mut #name { + unsafe fn raw(&self) -> napi::sys::napi_value { + unreachable!() + } + } } } diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__test__/typegen.spec.ts.md index 55b92aca..25d3615b 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__test__/typegen.spec.ts.md @@ -40,6 +40,8 @@ Generated by [AVA](https://avajs.dev). v: string | number␊ }␊ export function either4(input: string | number | boolean | Obj): number␊ + export function receiveClassOrNumber(either: number | JsClassForEither): number␊ + export function receiveMutClassOrNumber(either: number | JsClassForEither): number␊ /** default enum values are continuos i32s start from 0 */␊ export const enum Kind {␊ /** Barks */␊ @@ -200,6 +202,9 @@ Generated by [AVA](https://avajs.dev). static withName(name: string): ClassWithFactory␊ setName(name: string): this␊ }␊ + export class JsClassForEither {␊ + constructor()␊ + }␊ export namespace xxh3 {␊ export const ALIGNMENT: number␊ export function xxh3_64(input: Buffer): BigInt␊ diff --git a/examples/napi/__test__/typegen.spec.ts.snap b/examples/napi/__test__/typegen.spec.ts.snap index 36b7e036f4ba6bce14b14f0ea6f9d04b6bbe1ede..a929b2b0f48e25edcd535fc0e7a1bd7919bd7fe2 100644 GIT binary patch literal 2284 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 { @@ -320,6 +323,13 @@ test('return either', (t) => { t.is(returnEither(42), '42') }) +test('receive class reference in either', (t) => { + const c = new JsClassForEither() + t.is(receiveClassOrNumber(1), 2) + t.is(receiveClassOrNumber(c), 100) + t.is(receiveMutClassOrNumber(c), 100) +}) + test('either3', (t) => { t.is(either3(2), 2) t.is(either3('hello'), 'hello'.length) diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index cd2e9b02..31d68233 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -30,6 +30,8 @@ export interface Obj { v: string | number } export function either4(input: string | number | boolean | Obj): number +export function receiveClassOrNumber(either: number | JsClassForEither): number +export function receiveMutClassOrNumber(either: number | JsClassForEither): number /** default enum values are continuos i32s start from 0 */ export const enum Kind { /** Barks */ @@ -190,6 +192,9 @@ export class ClassWithFactory { static withName(name: string): ClassWithFactory setName(name: string): this } +export class JsClassForEither { + constructor() +} export namespace xxh3 { export const ALIGNMENT: number export function xxh3_64(input: Buffer): BigInt diff --git a/examples/napi/src/either.rs b/examples/napi/src/either.rs index 12ddccdc..175de708 100644 --- a/examples/napi/src/either.rs +++ b/examples/napi/src/either.rs @@ -55,3 +55,30 @@ fn either4(input: Either4) -> u32 { }, } } + +#[napi] +struct JsClassForEither {} + +#[napi] +impl JsClassForEither { + #[napi(constructor)] + pub fn new() -> Self { + JsClassForEither {} + } +} + +#[napi] +fn receive_class_or_number(either: Either) -> u32 { + match either { + Either::A(n) => n + 1, + Either::B(_) => 100, + } +} + +#[napi] +fn receive_mut_class_or_number(either: Either) -> u32 { + match either { + Either::A(n) => n + 1, + Either::B(_) => 100, + } +}