From cb9239d8dc14a2c79ceeb456e8318f3d635d8bb2 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Sun, 7 Aug 2022 01:16:28 +0800 Subject: [PATCH] fix(napi): either for #[napi(object)] types (#1258) --- .../src/bindgen_runtime/js_values/either.rs | 5 ++-- examples/napi/__test__/typegen.spec.ts.md | 10 ++++++++ examples/napi/__test__/typegen.spec.ts.snap | Bin 3436 -> 3471 bytes examples/napi/__test__/values.spec.ts | 7 +++++ examples/napi/index.d.ts | 10 ++++++++ examples/napi/src/either.rs | 24 ++++++++++++++++++ 6 files changed, 54 insertions(+), 2 deletions(-) diff --git a/crates/napi/src/bindgen_runtime/js_values/either.rs b/crates/napi/src/bindgen_runtime/js_values/either.rs index e84c25fb..c1ead47f 100644 --- a/crates/napi/src/bindgen_runtime/js_values/either.rs +++ b/crates/napi/src/bindgen_runtime/js_values/either.rs @@ -117,9 +117,10 @@ macro_rules! either_n { where $( $parameter: TypeName + FromNapiValue + ValidateNapiValue ),+ { unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result { + let mut ret = Err(Error::new(Status::InvalidArg, "Invalid value".to_owned())); $( - if unsafe { $parameter::validate(env, napi_val).is_ok() } { - unsafe { $parameter ::from_napi_value(env, napi_val).map(Self:: $parameter ) } + if unsafe { $parameter::validate(env, napi_val).is_ok() && { ret = $parameter ::from_napi_value(env, napi_val).map(Self:: $parameter ); ret.is_ok() } } { + ret } else )+ { diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__test__/typegen.spec.ts.md index 3ac6a9f6..ef2b65cc 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__test__/typegen.spec.ts.md @@ -65,6 +65,16 @@ Generated by [AVA](https://avajs.dev). export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number␊ export function returnEitherClass(input: number): number | JsClassForEither␊ export function eitherFromOption(): JsClassForEither | undefined␊ + export interface A {␊ + foo: number␊ + }␊ + export interface B {␊ + bar: number␊ + }␊ + export interface C {␊ + baz: number␊ + }␊ + export function eitherFromObjects(input: A | B | C): string␊ /** default enum values are continuos i32s start from 0 */␊ export const enum Kind {␊ /** Barks */␊ diff --git a/examples/napi/__test__/typegen.spec.ts.snap b/examples/napi/__test__/typegen.spec.ts.snap index 197cd296a56b03d0e61acc180b6b135b14e57064..3068b74ca194f4a5f01c846aad48cf54a35de93e 100644 GIT binary patch literal 3471 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 literal 3436 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 O-upl69=&qbFaQACO`Qh- diff --git a/examples/napi/__test__/values.spec.ts b/examples/napi/__test__/values.spec.ts index 5465716b..5b21a020 100644 --- a/examples/napi/__test__/values.spec.ts +++ b/examples/napi/__test__/values.spec.ts @@ -97,6 +97,7 @@ import { callbackReturnPromise, returnEitherClass, eitherFromOption, + eitherFromObjects, overrideIndividualArgOnFunction, overrideIndividualArgOnFunctionWithCbArg, createObjectWithClassField, @@ -544,6 +545,12 @@ test('either from option', (t) => { t.true(eitherFromOption() instanceof JsClassForEither) }) +test('either from objects', (t) => { + t.is(eitherFromObjects({ foo: 1 }), 'A') + t.is(eitherFromObjects({ bar: 2 }), 'B') + t.is(eitherFromObjects({ baz: 3 }), 'C') +}) + 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 4a0f1e55..bfbd2069 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -55,6 +55,16 @@ export function receiveMutClassOrNumber(either: number | JsClassForEither): numb export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number export function returnEitherClass(input: number): number | JsClassForEither export function eitherFromOption(): JsClassForEither | undefined +export interface A { + foo: number +} +export interface B { + bar: number +} +export interface C { + baz: number +} +export function eitherFromObjects(input: A | B | C): string /** default enum values are continuos i32s start from 0 */ export const enum Kind { /** Barks */ diff --git a/examples/napi/src/either.rs b/examples/napi/src/either.rs index d5c3498d..ab00955b 100644 --- a/examples/napi/src/either.rs +++ b/examples/napi/src/either.rs @@ -115,3 +115,27 @@ fn return_either_class(input: i32) -> Either { fn either_from_option() -> Either { Some(JsClassForEither {}).into() } + +#[napi(object)] +pub struct A { + pub foo: u32, +} + +#[napi(object)] +pub struct B { + pub bar: u32, +} + +#[napi(object)] +pub struct C { + pub baz: u32, +} + +#[napi] +pub fn either_from_objects(input: Either3) -> String { + match &input { + Either3::A(_) => "A".to_owned(), + Either3::B(_) => "B".to_owned(), + Either3::C(_) => "C".to_owned(), + } +}