diff --git a/crates/backend/src/codegen/fn.rs b/crates/backend/src/codegen/fn.rs index 930dab6d..2f828ffc 100644 --- a/crates/backend/src/codegen/fn.rs +++ b/crates/backend/src/codegen/fn.rs @@ -244,9 +244,17 @@ impl NapiFn { if let Some(ty) = &self.ret { if self.kind == FnKind::Constructor { - quote! { cb.construct(#js_name, #ret) } + if self.is_ret_result { + quote! { cb.construct(#js_name, #ret?) } + } else { + quote! { cb.construct(#js_name, #ret) } + } } else if self.kind == FnKind::Factory { - quote! { cb.factory(#js_name, #ret) } + if self.is_ret_result { + quote! { cb.factory(#js_name, #ret?) } + } else { + quote! { cb.factory(#js_name, #ret) } + } } else if self.is_ret_result { if self.is_async { quote! { diff --git a/crates/macro/src/parser/mod.rs b/crates/macro/src/parser/mod.rs index de4da2f6..7d6aa765 100644 --- a/crates/macro/src/parser/mod.rs +++ b/crates/macro/src/parser/mod.rs @@ -234,9 +234,8 @@ fn extract_callback_trait_types( fn extract_result_ty(ty: &syn::Type) -> BindgenResult> { match ty { - syn::Type::Path(syn::TypePath { qself: None, path }) if path.segments.len() == 1 => { - let segment = path.segments.first().unwrap(); - + syn::Type::Path(syn::TypePath { qself: None, path }) => { + let segment = path.segments.last().unwrap(); if segment.ident != "Result" { Ok(None) } else { diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__test__/typegen.spec.ts.md index 9408013c..a5412e72 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__test__/typegen.spec.ts.md @@ -61,6 +61,12 @@ Generated by [AVA](https://avajs.dev). export class Blake2BKey {␊ ␊ }␊ + export class Context {␊ + ␊ + constructor()␊ + static withData(data: string): Context␊ + method(): string␊ + }␊ export class ClassWithFactory {␊ name: string␊ static withName(name: string): ClassWithFactory␊ diff --git a/examples/napi/__test__/typegen.spec.ts.snap b/examples/napi/__test__/typegen.spec.ts.snap index d3478adf..0071ef33 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 6ccb5afd..d1548995 100644 --- a/examples/napi/__test__/values.spec.ts +++ b/examples/napi/__test__/values.spec.ts @@ -17,6 +17,7 @@ import { Kind, ClassWithFactory, CustomNumEnum, + Context, enumToI32, listObjKeys, createObj, @@ -96,6 +97,16 @@ test('class factory', (t) => { t.is(doge.name, '旺财') }) +test('class constructor return Result', (t) => { + const c = new Context() + t.is(c.method(), 'not empty') +}) + +test('class Factory return Result', (t) => { + const c = Context.withData('not empty') + t.is(c.method(), 'not empty') +}) + test('callback', (t) => { getCwd((cwd) => { t.is(cwd, process.cwd()) diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index c532a62e..caa26c4f 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -50,6 +50,12 @@ export class Blake2BHasher { } export class Blake2BKey { +} +export class Context { + + constructor() + static withData(data: string): Context + method(): string } export class ClassWithFactory { name: string diff --git a/examples/napi/src/class.rs b/examples/napi/src/class.rs index 7d6ef668..154d0117 100644 --- a/examples/napi/src/class.rs +++ b/examples/napi/src/class.rs @@ -1,4 +1,5 @@ use napi::bindgen_prelude::*; +use napi::Result; use crate::r#enum::Kind; @@ -75,3 +76,29 @@ impl Blake2bKey { self.0 } } + +#[napi] +pub struct Context { + data: String, +} + +// Test for return `napi::Result` and `Result` +#[napi] +impl Context { + #[napi(constructor)] + pub fn new() -> napi::Result { + Ok(Self { + data: "not empty".into(), + }) + } + + #[napi(factory)] + pub fn with_data(data: String) -> Result { + Ok(Self { data }) + } + + #[napi] + pub fn method(&self) -> String { + self.data.clone() + } +}