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 197cd296..3068b74c 100644 Binary files a/examples/napi/__test__/typegen.spec.ts.snap and b/examples/napi/__test__/typegen.spec.ts.snap differ 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(), + } +}