Skip to content

Commit

Permalink
Merge pull request #1272 from napi-rs/support-instanceof
Browse files Browse the repository at this point in the history
feat(napi-derive): implement instance_of for Class
  • Loading branch information
Brooooooklyn committed Aug 17, 2022
2 parents 8d0045f + 711372e commit 5030cfb
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 3 deletions.
32 changes: 30 additions & 2 deletions crates/backend/src/codegen/struct.rs
Expand Up @@ -283,6 +283,7 @@ impl NapiStruct {
} else {
quote! { impl napi::bindgen_prelude::ObjectFinalize for #name {} }
};
let instance_of_impl = self.gen_instance_of_impl(name, &js_name_str);
quote! {
impl napi::bindgen_prelude::ToNapiValue for #name {
unsafe fn to_napi_value(
Expand All @@ -303,7 +304,7 @@ impl NapiStruct {
}

#finalize_trait

#instance_of_impl
impl #name {
pub fn into_reference(val: #name, env: napi::Env) -> napi::Result<napi::bindgen_prelude::Reference<#name>> {
if let Some(ctor_ref) = napi::bindgen_prelude::get_class_constructor(#js_name_str) {
Expand Down Expand Up @@ -394,6 +395,7 @@ impl NapiStruct {
let name = &self.name;
let js_name_without_null = &self.js_name;
let js_name_str = format!("{}\0", &self.js_name);
let instance_of_impl = self.gen_instance_of_impl(name, &js_name_str);

let mut field_conversions = vec![];
let mut field_destructions = vec![];
Expand Down Expand Up @@ -466,7 +468,7 @@ impl NapiStruct {
}
}
}

#instance_of_impl
#finalize_trait
}
}
Expand Down Expand Up @@ -750,6 +752,32 @@ impl NapiStruct {
}
}
}

fn gen_instance_of_impl(&self, name: &Ident, js_name: &str) -> TokenStream {
quote! {
impl #name {
pub fn instance_of<V: napi::NapiRaw>(env: napi::Env, value: V) -> napi::Result<bool> {
if let Some(ctor_ref) = napi::bindgen_prelude::get_class_constructor(#js_name) {
let mut ctor = std::ptr::null_mut();
napi::check_status!(
unsafe { napi::sys::napi_get_reference_value(env.raw(), ctor_ref, &mut ctor) },
"Failed to get constructor reference of class `{}`",
#js_name
)?;
let mut is_instance_of = false;
napi::check_status!(
unsafe { napi::sys::napi_instanceof(env.raw(), value.raw(), ctor, &mut is_instance_of) },
"Failed to run instanceof for class `{}`",
#js_name
)?;
Ok(is_instance_of)
} else {
Err(napi::Error::new(napi::Status::GenericFailure, format!("Failed to get constructor of class `{}`", #js_name)))
}
}
}
}
}
}

impl TryToTokens for NapiImpl {
Expand Down
1 change: 1 addition & 0 deletions examples/napi/__test__/typegen.spec.ts.md
Expand Up @@ -267,6 +267,7 @@ Generated by [AVA](https://avajs.dev).
}␊
export class NinjaTurtle {␊
name: string␊
static isInstanceOf(value: unknown): boolean␊
/** Create your ninja turtle! 🐢 */␊
static newRaph(): NinjaTurtle␊
getMaskColor(): string␊
Expand Down
Binary file modified examples/napi/__test__/typegen.spec.ts.snap
Binary file not shown.
1 change: 1 addition & 0 deletions examples/napi/__test__/values.spec.ts
Expand Up @@ -191,6 +191,7 @@ test('class', (t) => {
t.is(assets.get(1)?.filePath, 1)
const turtle = NinjaTurtle.newRaph()
t.is(turtle.returnThis(), turtle)
t.is(NinjaTurtle.isInstanceOf(turtle), true)
})

test('class factory', (t) => {
Expand Down
1 change: 1 addition & 0 deletions examples/napi/index.d.ts
Expand Up @@ -257,6 +257,7 @@ export class AnimalWithDefaultConstructor {
}
export class NinjaTurtle {
name: string
static isInstanceOf(value: unknown): boolean
/** Create your ninja turtle! 🐢 */
static newRaph(): NinjaTurtle
getMaskColor(): string
Expand Down
7 changes: 6 additions & 1 deletion examples/napi/src/class.rs
@@ -1,5 +1,5 @@
use napi::{
bindgen_prelude::{Buffer, ClassInstance, ObjectFinalize, This, Uint8Array},
bindgen_prelude::{Buffer, ClassInstance, ObjectFinalize, This, Uint8Array, Unknown},
Env, Result,
};

Expand Down Expand Up @@ -214,6 +214,11 @@ pub struct NinjaTurtle {

#[napi]
impl NinjaTurtle {
#[napi]
pub fn is_instance_of(env: Env, value: Unknown) -> Result<bool> {
Self::instance_of(env, value)
}

/// Create your ninja turtle! 🐢
#[napi(factory)]
pub fn new_raph() -> Self {
Expand Down

0 comments on commit 5030cfb

Please sign in to comment.