feat(napi): implement more napi

This commit is contained in:
LongYinan 2020-08-24 16:04:03 +08:00
parent aaa6e31197
commit 98210cd771
No known key found for this signature in database
GPG key ID: A3FFE134A3E20881
5 changed files with 136 additions and 6 deletions

View file

@ -199,14 +199,14 @@ yarn test
| [napi_coerce_to_object](https://nodejs.org/api/n-api.html#n_api_napi_coerce_to_object) | 1 | v8.0.0 | ✅ | | [napi_coerce_to_object](https://nodejs.org/api/n-api.html#n_api_napi_coerce_to_object) | 1 | v8.0.0 | ✅ |
| [napi_coerce_to_string](https://nodejs.org/api/n-api.html#n_api_napi_coerce_to_string) | 1 | v8.0.0 | ✅ | | [napi_coerce_to_string](https://nodejs.org/api/n-api.html#n_api_napi_coerce_to_string) | 1 | v8.0.0 | ✅ |
| [napi_typeof](https://nodejs.org/api/n-api.html#n_api_napi_typeof) | 1 | v8.0.0 | ✅ | | [napi_typeof](https://nodejs.org/api/n-api.html#n_api_napi_typeof) | 1 | v8.0.0 | ✅ |
| [napi_instanceof](https://nodejs.org/api/n-api.html#n_api_napi_instanceof) | 1 | v8.0.0 | ⛔️ | | [napi_instanceof](https://nodejs.org/api/n-api.html#n_api_napi_instanceof) | 1 | v8.0.0 | |
| [napi_is_array](https://nodejs.org/api/n-api.html#n_api_napi_is_array) | 1 | v8.0.0 | ✅ | | [napi_is_array](https://nodejs.org/api/n-api.html#n_api_napi_is_array) | 1 | v8.0.0 | ✅ |
| [napi_is_arraybuffer](https://nodejs.org/api/n-api.html#n_api_napi_is_arraybuffer) | 1 | v8.0.0 | ✅ | | [napi_is_arraybuffer](https://nodejs.org/api/n-api.html#n_api_napi_is_arraybuffer) | 1 | v8.0.0 | ✅ |
| [napi_is_buffer](https://nodejs.org/api/n-api.html#n_api_napi_is_buffer) | 1 | v8.0.0 | ✅ | | [napi_is_buffer](https://nodejs.org/api/n-api.html#n_api_napi_is_buffer) | 1 | v8.0.0 | ✅ |
| [napi_is_date](https://nodejs.org/api/n-api.html#n_api_napi_is_date) | 1 | v8.0.0 | ✅ | | [napi_is_date](https://nodejs.org/api/n-api.html#n_api_napi_is_date) | 1 | v8.0.0 | ✅ |
| [napi_is_error](https://nodejs.org/api/n-api.html#n_api_napi_is_error_1) | 1 | v8.0.0 | ⛔️ | | [napi_is_error](https://nodejs.org/api/n-api.html#n_api_napi_is_error_1) | 1 | v8.0.0 | |
| [napi_is_typedarray](https://nodejs.org/api/n-api.html#n_api_napi_is_typedarray) | 1 | v8.0.0 | ⛔️ | | [napi_is_typedarray](https://nodejs.org/api/n-api.html#n_api_napi_is_typedarray) | 1 | v8.0.0 | |
| [napi_is_dataview](https://nodejs.org/api/n-api.html#n_api_napi_is_dataview) | 1 | v8.3.0 | ⛔️ | | [napi_is_dataview](https://nodejs.org/api/n-api.html#n_api_napi_is_dataview) | 1 | v8.3.0 | |
| [napi_strict_equals](https://nodejs.org/api/n-api.html#n_api_napi_strict_equals) | 1 | v8.0.0 | ⛔️ | | [napi_strict_equals](https://nodejs.org/api/n-api.html#n_api_napi_strict_equals) | 1 | v8.0.0 | |
| [napi_detach_arraybuffer](https://nodejs.org/api/n-api.html#n_api_napi_detach_arraybuffer) | Experimental | v13.3.0 | ⛔️ | | [napi_detach_arraybuffer](https://nodejs.org/api/n-api.html#n_api_napi_detach_arraybuffer) | Experimental | v13.3.0 | ⛔️ |
| [napi_is_detached_arraybuffer](https://nodejs.org/api/n-api.html#n_api_napi_is_detached_arraybuffer) | Experimental | v13.3.0 | ⛔️ | | [napi_is_detached_arraybuffer](https://nodejs.org/api/n-api.html#n_api_napi_is_detached_arraybuffer) | Experimental | v13.3.0 | ⛔️ |

View file

@ -608,6 +608,15 @@ impl Env {
Ok(JsObject::from_raw_unchecked(self.0, raw_promise)) Ok(JsObject::from_raw_unchecked(self.0, raw_promise))
} }
#[inline]
pub fn strict_equals<A: NapiValue, B: NapiValue>(&self, a: A, b: B) -> Result<bool> {
let mut result = false;
check_status(unsafe {
sys::napi_strict_equals(self.0, a.raw_value(), b.raw_value(), &mut result)
})?;
Ok(result)
}
#[inline] #[inline]
pub fn get_node_version(&self) -> Result<NodeVersion> { pub fn get_node_version(&self) -> Result<NodeVersion> {
let mut result = ptr::null(); let mut result = ptr::null();

View file

@ -150,6 +150,41 @@ macro_rules! impl_js_value_methods {
check_status(status)?; check_status(status)?;
Ok(is_date) Ok(is_date)
} }
#[inline]
pub fn is_error(&self) -> Result<bool> {
let mut result = false;
check_status(unsafe { sys::napi_is_error(self.0.env, self.0.value, &mut result) })?;
Ok(result)
}
#[inline]
pub fn is_typedarray(&self) -> Result<bool> {
let mut result = false;
check_status(unsafe { sys::napi_is_typedarray(self.0.env, self.0.value, &mut result) })?;
Ok(result)
}
#[inline]
pub fn is_dataview(&self) -> Result<bool> {
let mut result = false;
check_status(unsafe { sys::napi_is_dataview(self.0.env, self.0.value, &mut result) })?;
Ok(result)
}
#[inline]
pub fn instanceof<Constructor: NapiValue>(&self, constructor: Constructor) -> Result<bool> {
let mut result = false;
check_status(unsafe {
sys::napi_instanceof(
self.0.env,
self.0.value,
constructor.raw_value(),
&mut result,
)
})?;
Ok(result)
}
} }
}; };
} }

View file

@ -0,0 +1,49 @@
const test = require('ava')
const bindings = require('../index.node')
test('instanceof', (t) => {
const day = new Date()
t.true(bindings.instanceof(day, Date))
t.false(bindings.instanceof(day, Number))
t.false(bindings.instanceof(1, Date))
})
test('is_error', (t) => {
t.true(bindings.isError(new Error()))
t.true(bindings.isError(new TypeError()))
t.true(bindings.isError(new SyntaxError()))
t.false(bindings.isError('111'))
t.false(bindings.isError(2))
t.false(bindings.isError(Symbol()))
})
test('is_typedarray', (t) => {
t.true(bindings.isTypedarray(new Uint8Array()))
t.true(bindings.isTypedarray(new Uint16Array()))
t.true(bindings.isTypedarray(new Uint32Array()))
t.true(bindings.isTypedarray(new Int8Array()))
t.true(bindings.isTypedarray(new Int16Array()))
t.true(bindings.isTypedarray(new Int32Array()))
t.true(bindings.isTypedarray(Buffer.from('123')))
t.false(bindings.isTypedarray(Buffer.from('123').buffer))
t.false(bindings.isTypedarray([]))
})
test('is_dataview', (t) => {
const data = new Uint8Array(100)
t.true(bindings.isDataview(new DataView(data.buffer)))
t.false(bindings.isDataview(Buffer.from('123')))
})
test('strict_equals', (t) => {
const a = {
foo: 'bar',
}
const b = { ...a }
t.false(bindings.strictEquals(a, b))
t.false(bindings.strictEquals(1, '1'))
t.false(bindings.strictEquals(null, undefined))
t.false(bindings.strictEquals(NaN, NaN))
t.true(bindings.strictEquals(a, a))
})

View file

@ -3,7 +3,7 @@ extern crate napi;
#[macro_use] #[macro_use]
extern crate napi_derive; extern crate napi_derive;
use napi::{CallContext, Error, JsString, JsUnknown, Module, Result, Status}; use napi::{CallContext, Error, JsBoolean, JsString, JsUnknown, Module, Result, Status};
#[cfg(napi4)] #[cfg(napi4)]
mod libuv; mod libuv;
@ -71,6 +71,11 @@ fn init(module: &mut Module) -> Result<()> {
module.create_named_method("dynamicArgumentLength", dynamic_argument_length)?; module.create_named_method("dynamicArgumentLength", dynamic_argument_length)?;
module.create_named_method("createTestClass", class::create_test_class)?; module.create_named_method("createTestClass", class::create_test_class)?;
module.create_named_method("concatString", string::concat_string)?; module.create_named_method("concatString", string::concat_string)?;
module.create_named_method("instanceof", instanceof)?;
module.create_named_method("isError", is_error)?;
module.create_named_method("isTypedarray", is_typedarray)?;
module.create_named_method("isDataview", is_dataview)?;
module.create_named_method("strictEquals", strict_equals)?;
#[cfg(napi4)] #[cfg(napi4)]
module.create_named_method("testExecuteTokioReadfile", test_execute_tokio_readfile)?; module.create_named_method("testExecuteTokioReadfile", test_execute_tokio_readfile)?;
#[cfg(napi4)] #[cfg(napi4)]
@ -118,3 +123,35 @@ fn test_throw_with_reason(ctx: CallContext) -> Result<JsUnknown> {
pub fn test_throw_with_panic(_ctx: CallContext) -> Result<JsUnknown> { pub fn test_throw_with_panic(_ctx: CallContext) -> Result<JsUnknown> {
panic!("don't panic."); panic!("don't panic.");
} }
#[js_function(2)]
pub fn instanceof(ctx: CallContext) -> Result<JsBoolean> {
let object = ctx.get::<JsUnknown>(0)?;
let constructor = ctx.get::<JsUnknown>(1)?;
ctx.env.get_boolean(object.instanceof(constructor)?)
}
#[js_function(1)]
pub fn is_error(ctx: CallContext) -> Result<JsBoolean> {
let js_value = ctx.get::<JsUnknown>(0)?;
ctx.env.get_boolean(js_value.is_error()?)
}
#[js_function(1)]
pub fn is_typedarray(ctx: CallContext) -> Result<JsBoolean> {
let js_value = ctx.get::<JsUnknown>(0)?;
ctx.env.get_boolean(js_value.is_typedarray()?)
}
#[js_function(1)]
pub fn is_dataview(ctx: CallContext) -> Result<JsBoolean> {
let js_value = ctx.get::<JsUnknown>(0)?;
ctx.env.get_boolean(js_value.is_dataview()?)
}
#[js_function(2)]
pub fn strict_equals(ctx: CallContext) -> Result<JsBoolean> {
let a: JsUnknown = ctx.get(0)?;
let b: JsUnknown = ctx.get(1)?;
ctx.env.get_boolean(ctx.env.strict_equals(a, b)?)
}