fix(napi): either for #[napi(object)] types (#1258)

This commit is contained in:
LongYinan 2022-08-07 01:16:28 +08:00 committed by GitHub
parent 6a9fdba8b6
commit cb9239d8dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 54 additions and 2 deletions

View file

@ -117,9 +117,10 @@ macro_rules! either_n {
where $( $parameter: TypeName + FromNapiValue + ValidateNapiValue ),+ where $( $parameter: TypeName + FromNapiValue + ValidateNapiValue ),+
{ {
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result<Self> { unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result<Self> {
let mut ret = Err(Error::new(Status::InvalidArg, "Invalid value".to_owned()));
$( $(
if unsafe { $parameter::validate(env, napi_val).is_ok() } { if unsafe { $parameter::validate(env, napi_val).is_ok() && { ret = $parameter ::from_napi_value(env, napi_val).map(Self:: $parameter ); ret.is_ok() } } {
unsafe { $parameter ::from_napi_value(env, napi_val).map(Self:: $parameter ) } ret
} else } else
)+ )+
{ {

View file

@ -65,6 +65,16 @@ Generated by [AVA](https://avajs.dev).
export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number␊ export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number␊
export function returnEitherClass(input: number): number | JsClassForEither␊ export function returnEitherClass(input: number): number | JsClassForEither␊
export function eitherFromOption(): JsClassForEither | undefined␊ 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 */␊ /** default enum values are continuos i32s start from 0 */␊
export const enum Kind {␊ export const enum Kind {␊
/** Barks */␊ /** Barks */␊

View file

@ -97,6 +97,7 @@ import {
callbackReturnPromise, callbackReturnPromise,
returnEitherClass, returnEitherClass,
eitherFromOption, eitherFromOption,
eitherFromObjects,
overrideIndividualArgOnFunction, overrideIndividualArgOnFunction,
overrideIndividualArgOnFunctionWithCbArg, overrideIndividualArgOnFunctionWithCbArg,
createObjectWithClassField, createObjectWithClassField,
@ -544,6 +545,12 @@ test('either from option', (t) => {
t.true(eitherFromOption() instanceof JsClassForEither) 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) => { test('either3', (t) => {
t.is(either3(2), 2) t.is(either3(2), 2)
t.is(either3('hello'), 'hello'.length) t.is(either3('hello'), 'hello'.length)

View file

@ -55,6 +55,16 @@ export function receiveMutClassOrNumber(either: number | JsClassForEither): numb
export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number
export function returnEitherClass(input: number): number | JsClassForEither export function returnEitherClass(input: number): number | JsClassForEither
export function eitherFromOption(): JsClassForEither | undefined 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 */ /** default enum values are continuos i32s start from 0 */
export const enum Kind { export const enum Kind {
/** Barks */ /** Barks */

View file

@ -115,3 +115,27 @@ fn return_either_class(input: i32) -> Either<u32, JsClassForEither> {
fn either_from_option() -> Either<JsClassForEither, Undefined> { fn either_from_option() -> Either<JsClassForEither, Undefined> {
Some(JsClassForEither {}).into() 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<A, B, C>) -> String {
match &input {
Either3::A(_) => "A".to_owned(),
Either3::B(_) => "B".to_owned(),
Either3::C(_) => "C".to_owned(),
}
}