Merge pull request #852 from napi-rs/global
feat(napi): support JsGlobal in `Env`
This commit is contained in:
commit
c0a89834c2
15 changed files with 148 additions and 100 deletions
2
.github/workflows/lint.yaml
vendored
2
.github/workflows/lint.yaml
vendored
|
@ -61,7 +61,7 @@ jobs:
|
||||||
run: cargo fmt -- --check
|
run: cargo fmt -- --check
|
||||||
|
|
||||||
- name: Clippy
|
- name: Clippy
|
||||||
run: cargo clippy
|
run: cargo clippy --all-features
|
||||||
|
|
||||||
- name: Clear the cargo caches
|
- name: Clear the cargo caches
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -242,7 +242,7 @@ yarn test
|
||||||
| T: Fn(...) -> Result<T> | Function | 1 | v8.0.0 |
|
| T: Fn(...) -> Result<T> | Function | 1 | v8.0.0 |
|
||||||
| Async/Future | Promise<T> | 4 | v10.6.0 | async |
|
| Async/Future | Promise<T> | 4 | v10.6.0 | async |
|
||||||
| AsyncTask | Promise<T> | 1 | v8.5.0 |
|
| AsyncTask | Promise<T> | 1 | v8.5.0 |
|
||||||
| (NOT YET) | global | 1 | v8.0.0 |
|
| JsGlobal | global | 1 | v8.0.0 |
|
||||||
| JsSymbol | Symbol | 1 | v8.0.0 |
|
| JsSymbol | Symbol | 1 | v8.0.0 |
|
||||||
| (NOT YET) | ArrayBuffer/TypedArray | 1 | v8.0.0 |
|
| (NOT YET) | ArrayBuffer/TypedArray | 1 | v8.0.0 |
|
||||||
| JsFunction | threadsafe function | 4 | v10.6.0 | napi4 |
|
| JsFunction | threadsafe function | 4 | v10.6.0 | napi4 |
|
||||||
|
|
|
@ -75,6 +75,7 @@ static KNOWN_TYPES: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||||
("external", "object"),
|
("external", "object"),
|
||||||
("AbortSignal", "AbortSignal"),
|
("AbortSignal", "AbortSignal"),
|
||||||
("JsFunction", "(...args: any[]) => any"),
|
("JsFunction", "(...args: any[]) => any"),
|
||||||
|
("JsGlobal", "typeof global"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
map
|
map
|
||||||
|
|
|
@ -1,22 +1,57 @@
|
||||||
use crate::{sys, Result};
|
use std::cell::RefCell;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
use super::{Array, Object};
|
use crate::{check_status, sys, JsGlobal, JsNull, JsUndefined, NapiValue, Result};
|
||||||
|
|
||||||
#[repr(transparent)]
|
use super::Array;
|
||||||
pub struct Env(sys::napi_env);
|
|
||||||
|
|
||||||
impl From<sys::napi_env> for Env {
|
pub use crate::Env;
|
||||||
fn from(raw_env: sys::napi_env) -> Env {
|
|
||||||
Env(raw_env)
|
thread_local! {
|
||||||
}
|
static JS_UNDEFINED: RefCell<Option<JsUndefined>> = RefCell::default();
|
||||||
|
static JS_NULL: RefCell<Option<JsNull>> = RefCell::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Env {
|
impl Env {
|
||||||
pub fn create_object(&self) -> Result<Object> {
|
|
||||||
Object::new(self.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_array(&self, len: u32) -> Result<Array> {
|
pub fn create_array(&self, len: u32) -> Result<Array> {
|
||||||
Array::new(self.0, len)
|
Array::new(self.0, len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get [JsUndefined](./struct.JsUndefined.html) value
|
||||||
|
pub fn get_undefined(&self) -> Result<JsUndefined> {
|
||||||
|
if let Some(js_undefined) = JS_UNDEFINED.with(|x| *x.borrow()) {
|
||||||
|
return Ok(js_undefined);
|
||||||
|
}
|
||||||
|
let mut raw_value = ptr::null_mut();
|
||||||
|
check_status!(unsafe { sys::napi_get_undefined(self.0, &mut raw_value) })?;
|
||||||
|
let js_undefined = unsafe { JsUndefined::from_raw_unchecked(self.0, raw_value) };
|
||||||
|
JS_UNDEFINED.with(|x| x.borrow_mut().replace(js_undefined));
|
||||||
|
Ok(js_undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_null(&self) -> Result<JsNull> {
|
||||||
|
if let Some(js_null) = JS_NULL.with(|cell| *cell.borrow()) {
|
||||||
|
return Ok(js_null);
|
||||||
|
}
|
||||||
|
let mut raw_value = ptr::null_mut();
|
||||||
|
check_status!(unsafe { sys::napi_get_null(self.0, &mut raw_value) })?;
|
||||||
|
let js_null = unsafe { JsNull::from_raw_unchecked(self.0, raw_value) };
|
||||||
|
JS_NULL.with(|js_null_cell| {
|
||||||
|
js_null_cell.borrow_mut().replace(js_null);
|
||||||
|
});
|
||||||
|
Ok(js_null)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_global(&self) -> Result<JsGlobal> {
|
||||||
|
let mut global = std::ptr::null_mut();
|
||||||
|
crate::check_status!(
|
||||||
|
unsafe { sys::napi_get_global(self.0, &mut global) },
|
||||||
|
"Get global object from Env failed"
|
||||||
|
)?;
|
||||||
|
Ok(JsGlobal(crate::Value {
|
||||||
|
value: global,
|
||||||
|
env: self.0,
|
||||||
|
value_type: crate::ValueType::Object,
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
use crate::{bindgen_prelude::*, check_status, sys, type_of, ValueType};
|
use crate::{bindgen_prelude::*, check_status, sys, type_of, JsObject, ValueType};
|
||||||
use std::{ffi::CString, ptr};
|
use std::{ffi::CString, ptr};
|
||||||
|
|
||||||
pub struct Object {
|
pub type Object = JsObject;
|
||||||
pub(crate) env: sys::napi_env,
|
|
||||||
pub(crate) inner: sys::napi_value,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Object {
|
impl Object {
|
||||||
pub(crate) fn new(env: sys::napi_env) -> Result<Self> {
|
pub(crate) fn new(env: sys::napi_env) -> Result<Self> {
|
||||||
|
@ -16,7 +13,11 @@ impl Object {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Object { env, inner: ptr })
|
Ok(Self(crate::Value {
|
||||||
|
env,
|
||||||
|
value: ptr,
|
||||||
|
value_type: ValueType::Object,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<K: AsRef<str>, V: FromNapiValue>(&self, field: K) -> Result<Option<V>> {
|
pub fn get<K: AsRef<str>, V: FromNapiValue>(&self, field: K) -> Result<Option<V>> {
|
||||||
|
@ -26,17 +27,17 @@ impl Object {
|
||||||
let mut ret = ptr::null_mut();
|
let mut ret = ptr::null_mut();
|
||||||
|
|
||||||
check_status!(
|
check_status!(
|
||||||
sys::napi_get_named_property(self.env, self.inner, c_field.as_ptr(), &mut ret),
|
sys::napi_get_named_property(self.0.env, self.0.value, c_field.as_ptr(), &mut ret),
|
||||||
"Failed to get property with field `{}`",
|
"Failed to get property with field `{}`",
|
||||||
c_field.to_string_lossy(),
|
c_field.to_string_lossy(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let ty = type_of!(self.env, ret)?;
|
let ty = type_of!(self.0.env, ret)?;
|
||||||
|
|
||||||
Ok(if ty == ValueType::Undefined {
|
Ok(if ty == ValueType::Undefined {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(V::from_napi_value(self.env, ret)?)
|
Some(V::from_napi_value(self.0.env, ret)?)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,10 +46,10 @@ impl Object {
|
||||||
let c_field = CString::new(field.as_ref())?;
|
let c_field = CString::new(field.as_ref())?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let napi_val = V::to_napi_value(self.env, val)?;
|
let napi_val = V::to_napi_value(self.0.env, val)?;
|
||||||
|
|
||||||
check_status!(
|
check_status!(
|
||||||
sys::napi_set_named_property(self.env, self.inner, c_field.as_ptr(), napi_val),
|
sys::napi_set_named_property(self.0.env, self.0.value, c_field.as_ptr(), napi_val),
|
||||||
"Failed to set property with field `{}`",
|
"Failed to set property with field `{}`",
|
||||||
c_field.to_string_lossy(),
|
c_field.to_string_lossy(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -61,12 +62,12 @@ impl Object {
|
||||||
let mut names = ptr::null_mut();
|
let mut names = ptr::null_mut();
|
||||||
unsafe {
|
unsafe {
|
||||||
check_status!(
|
check_status!(
|
||||||
sys::napi_get_property_names(obj.env, obj.inner, &mut names),
|
sys::napi_get_property_names(obj.0.env, obj.0.value, &mut names),
|
||||||
"Failed to get property names of given object"
|
"Failed to get property names of given object"
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let names = unsafe { Array::from_napi_value(obj.env, names)? };
|
let names = unsafe { Array::from_napi_value(obj.0.env, names)? };
|
||||||
let mut ret = vec![];
|
let mut ret = vec![];
|
||||||
|
|
||||||
for i in 0..names.len() {
|
for i in 0..names.len() {
|
||||||
|
@ -86,25 +87,3 @@ impl TypeName for Object {
|
||||||
ValueType::Object
|
ValueType::Object
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToNapiValue for Object {
|
|
||||||
unsafe fn to_napi_value(_env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
|
|
||||||
Ok(val.inner)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromNapiValue for Object {
|
|
||||||
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
|
|
||||||
let value_type = type_of!(env, napi_val)?;
|
|
||||||
match value_type {
|
|
||||||
ValueType::Object => Ok(Self {
|
|
||||||
inner: napi_val,
|
|
||||||
env,
|
|
||||||
}),
|
|
||||||
_ => Err(Error::new(
|
|
||||||
Status::InvalidArg,
|
|
||||||
"Given napi value is not an object".to_owned(),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
|
|
||||||
use crate::{bindgen_runtime::Null, check_status, sys, type_of, Error, Result, Status, ValueType};
|
use crate::{
|
||||||
|
bindgen_runtime::Null, check_status, sys, type_of, Error, JsObject, Result, Status, ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{FromNapiValue, Object, ToNapiValue};
|
use super::{FromNapiValue, Object, ToNapiValue};
|
||||||
|
|
||||||
|
@ -78,10 +80,11 @@ impl ToNapiValue for Map<String, Value> {
|
||||||
|
|
||||||
impl FromNapiValue for Map<String, Value> {
|
impl FromNapiValue for Map<String, Value> {
|
||||||
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
|
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
|
||||||
let obj = Object {
|
let obj = JsObject(crate::Value {
|
||||||
env,
|
env,
|
||||||
inner: napi_val,
|
value: napi_val,
|
||||||
};
|
value_type: ValueType::Object,
|
||||||
|
});
|
||||||
|
|
||||||
let mut map = Map::new();
|
let mut map = Map::new();
|
||||||
for key in Object::keys(&obj)?.into_iter() {
|
for key in Object::keys(&obj)?.into_iter() {
|
||||||
|
|
|
@ -43,25 +43,18 @@ pub type Callback = extern "C" fn(sys::napi_env, sys::napi_callback_info) -> sys
|
||||||
/// Notification of this event is delivered through the callbacks given to `Env::add_env_cleanup_hook` and `Env::set_instance_data`.
|
/// Notification of this event is delivered through the callbacks given to `Env::add_env_cleanup_hook` and `Env::set_instance_data`.
|
||||||
pub struct Env(pub(crate) sys::napi_env);
|
pub struct Env(pub(crate) sys::napi_env);
|
||||||
|
|
||||||
|
impl From<sys::napi_env> for Env {
|
||||||
|
fn from(env: sys::napi_env) -> Self {
|
||||||
|
Env(env)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Env {
|
impl Env {
|
||||||
#[allow(clippy::missing_safety_doc)]
|
#[allow(clippy::missing_safety_doc)]
|
||||||
pub unsafe fn from_raw(env: sys::napi_env) -> Self {
|
pub unsafe fn from_raw(env: sys::napi_env) -> Self {
|
||||||
Env(env)
|
Env(env)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get [JsUndefined](./struct.JsUndefined.html) value
|
|
||||||
pub fn get_undefined(&self) -> Result<JsUndefined> {
|
|
||||||
let mut raw_value = ptr::null_mut();
|
|
||||||
check_status!(unsafe { sys::napi_get_undefined(self.0, &mut raw_value) })?;
|
|
||||||
Ok(unsafe { JsUndefined::from_raw_unchecked(self.0, raw_value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_null(&self) -> Result<JsNull> {
|
|
||||||
let mut raw_value = ptr::null_mut();
|
|
||||||
check_status!(unsafe { sys::napi_get_null(self.0, &mut raw_value) })?;
|
|
||||||
Ok(unsafe { JsNull::from_raw_unchecked(self.0, raw_value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_boolean(&self, value: bool) -> Result<JsBoolean> {
|
pub fn get_boolean(&self, value: bool) -> Result<JsBoolean> {
|
||||||
let mut raw_value = ptr::null_mut();
|
let mut raw_value = ptr::null_mut();
|
||||||
check_status!(unsafe { sys::napi_get_boolean(self.0, value, &mut raw_value) })?;
|
check_status!(unsafe { sys::napi_get_boolean(self.0, value, &mut raw_value) })?;
|
||||||
|
@ -231,7 +224,7 @@ impl Env {
|
||||||
Ok(unsafe { JsObject::from_raw_unchecked(self.0, raw_value) })
|
Ok(unsafe { JsObject::from_raw_unchecked(self.0, raw_value) })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_array(&self) -> Result<JsObject> {
|
pub fn create_empty_array(&self) -> Result<JsObject> {
|
||||||
let mut raw_value = ptr::null_mut();
|
let mut raw_value = ptr::null_mut();
|
||||||
check_status!(unsafe { sys::napi_create_array(self.0, &mut raw_value) })?;
|
check_status!(unsafe { sys::napi_create_array(self.0, &mut raw_value) })?;
|
||||||
Ok(unsafe { JsObject::from_raw_unchecked(self.0, raw_value) })
|
Ok(unsafe { JsObject::from_raw_unchecked(self.0, raw_value) })
|
||||||
|
@ -949,12 +942,6 @@ impl Env {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_global(&self) -> Result<JsGlobal> {
|
|
||||||
let mut raw_global = ptr::null_mut();
|
|
||||||
check_status!(unsafe { sys::napi_get_global(self.0, &mut raw_global) })?;
|
|
||||||
Ok(unsafe { JsGlobal::from_raw_unchecked(self.0, raw_global) })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_napi_version(&self) -> Result<u32> {
|
pub fn get_napi_version(&self) -> Result<u32> {
|
||||||
let global = self.get_global()?;
|
let global = self.get_global()?;
|
||||||
let process: JsObject = global.get_named_property("process")?;
|
let process: JsObject = global.get_named_property("process")?;
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub struct JsTimeout(pub(crate) Value);
|
||||||
|
|
||||||
impl JsGlobal {
|
impl JsGlobal {
|
||||||
pub fn set_interval(&self, handler: JsFunction, interval: f64) -> Result<JsTimeout> {
|
pub fn set_interval(&self, handler: JsFunction, interval: f64) -> Result<JsTimeout> {
|
||||||
let func: JsFunction = self.get_named_property("setInterval")?;
|
let func: JsFunction = self.get_named_property_unchecked("setInterval")?;
|
||||||
func
|
func
|
||||||
.call(
|
.call(
|
||||||
None,
|
None,
|
||||||
|
@ -24,14 +24,14 @@ impl JsGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_interval(&self, timer: JsTimeout) -> Result<JsUndefined> {
|
pub fn clear_interval(&self, timer: JsTimeout) -> Result<JsUndefined> {
|
||||||
let func: JsFunction = self.get_named_property("clearInterval")?;
|
let func: JsFunction = self.get_named_property_unchecked("clearInterval")?;
|
||||||
func
|
func
|
||||||
.call(None, &[timer.into_unknown()])
|
.call(None, &[timer.into_unknown()])
|
||||||
.and_then(|ret| ret.try_into())
|
.and_then(|ret| ret.try_into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_timeout(&self, handler: JsFunction, interval: f64) -> Result<JsTimeout> {
|
pub fn set_timeout(&self, handler: JsFunction, interval: f64) -> Result<JsTimeout> {
|
||||||
let func: JsFunction = self.get_named_property("setTimeout")?;
|
let func: JsFunction = self.get_named_property_unchecked("setTimeout")?;
|
||||||
func
|
func
|
||||||
.call(
|
.call(
|
||||||
None,
|
None,
|
||||||
|
@ -46,7 +46,7 @@ impl JsGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_timeout(&self, timer: JsTimeout) -> Result<JsUndefined> {
|
pub fn clear_timeout(&self, timer: JsTimeout) -> Result<JsUndefined> {
|
||||||
let func: JsFunction = self.get_named_property("clearTimeout")?;
|
let func: JsFunction = self.get_named_property_unchecked("clearTimeout")?;
|
||||||
func
|
func
|
||||||
.call(None, &[timer.into_unknown()])
|
.call(None, &[timer.into_unknown()])
|
||||||
.and_then(|ret| ret.try_into())
|
.and_then(|ret| ret.try_into())
|
||||||
|
|
|
@ -8,7 +8,6 @@ use std::ptr;
|
||||||
#[cfg(feature = "napi5")]
|
#[cfg(feature = "napi5")]
|
||||||
use super::check_status;
|
use super::check_status;
|
||||||
use super::Value;
|
use super::Value;
|
||||||
use crate::bindgen_runtime::TypeName;
|
|
||||||
#[cfg(feature = "napi5")]
|
#[cfg(feature = "napi5")]
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
#[cfg(feature = "napi5")]
|
#[cfg(feature = "napi5")]
|
||||||
|
@ -17,20 +16,9 @@ use crate::Env;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
#[cfg(feature = "napi5")]
|
#[cfg(feature = "napi5")]
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::ValueType;
|
|
||||||
|
|
||||||
pub struct JsObject(pub(crate) Value);
|
pub struct JsObject(pub(crate) Value);
|
||||||
|
|
||||||
impl TypeName for JsObject {
|
|
||||||
fn type_name() -> &'static str {
|
|
||||||
"Object"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn value_type() -> crate::ValueType {
|
|
||||||
ValueType::Object
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "napi5")]
|
#[cfg(feature = "napi5")]
|
||||||
pub struct FinalizeContext<T: 'static, Hint: 'static> {
|
pub struct FinalizeContext<T: 'static, Hint: 'static> {
|
||||||
pub env: Env,
|
pub env: Env,
|
||||||
|
|
|
@ -7,7 +7,7 @@ use napi::{
|
||||||
|
|
||||||
#[contextless_function]
|
#[contextless_function]
|
||||||
fn test_create_array(env: Env) -> ContextlessResult<JsObject> {
|
fn test_create_array(env: Env) -> ContextlessResult<JsObject> {
|
||||||
env.create_array().map(Some)
|
env.create_empty_array().map(Some)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[js_function(1)]
|
#[js_function(1)]
|
||||||
|
|
|
@ -34,6 +34,9 @@ Generated by [AVA](https://avajs.dev).
|
||||||
export function fibonacci(n: number): number␊
|
export function fibonacci(n: number): number␊
|
||||||
export function listObjKeys(obj: object): Array<string>␊
|
export function listObjKeys(obj: object): Array<string>␊
|
||||||
export function createObj(): object␊
|
export function createObj(): object␊
|
||||||
|
export function getGlobal(): typeof global␊
|
||||||
|
export function getUndefined(): JsUndefined␊
|
||||||
|
export function getNull(): JsNull␊
|
||||||
export function asyncPlus100(p: Promise<number>): Promise<number>␊
|
export function asyncPlus100(p: Promise<number>): Promise<number>␊
|
||||||
interface PackageJson {␊
|
interface PackageJson {␊
|
||||||
name: string␊
|
name: string␊
|
||||||
|
|
Binary file not shown.
|
@ -41,6 +41,9 @@ import {
|
||||||
callThreadsafeFunction,
|
callThreadsafeFunction,
|
||||||
threadsafeFunctionThrowError,
|
threadsafeFunctionThrowError,
|
||||||
asyncPlus100,
|
asyncPlus100,
|
||||||
|
getGlobal,
|
||||||
|
getUndefined,
|
||||||
|
getNull,
|
||||||
} from '../'
|
} from '../'
|
||||||
|
|
||||||
test('number', (t) => {
|
test('number', (t) => {
|
||||||
|
@ -137,6 +140,22 @@ test('object', (t) => {
|
||||||
t.deepEqual(createObj(), { test: 1 })
|
t.deepEqual(createObj(), { test: 1 })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('global', (t) => {
|
||||||
|
t.is(getGlobal(), global)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('get undefined', (t) => {
|
||||||
|
for (const _ of Array.from({ length: 100 })) {
|
||||||
|
t.is(getUndefined(), undefined)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('get null', (t) => {
|
||||||
|
for (const _ of Array.from({ length: 100 })) {
|
||||||
|
t.is(getNull(), null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
test('Option', (t) => {
|
test('Option', (t) => {
|
||||||
t.is(mapOption(null), null)
|
t.is(mapOption(null), null)
|
||||||
t.is(mapOption(3), 4)
|
t.is(mapOption(3), 4)
|
||||||
|
|
36
examples/napi/index.d.ts
vendored
36
examples/napi/index.d.ts
vendored
|
@ -7,7 +7,9 @@ export function bigintAdd(a: BigInt, b: BigInt): BigInt
|
||||||
export function createBigInt(): BigInt
|
export function createBigInt(): BigInt
|
||||||
export function createBigIntI64(): BigInt
|
export function createBigIntI64(): BigInt
|
||||||
export function getCwd(callback: (arg0: string) => void): void
|
export function getCwd(callback: (arg0: string) => void): void
|
||||||
export function readFile(callback: (arg0: Error | undefined, arg1: string | null) => void): void
|
export function readFile(
|
||||||
|
callback: (arg0: Error | undefined, arg1: string | null) => void,
|
||||||
|
): void
|
||||||
export function eitherStringOrNumber(input: string | number): number
|
export function eitherStringOrNumber(input: string | number): number
|
||||||
export function returnEither(input: number): string | number
|
export function returnEither(input: number): string | number
|
||||||
export function either3(input: string | number | boolean): number
|
export function either3(input: string | number | boolean): number
|
||||||
|
@ -15,8 +17,21 @@ interface Obj {
|
||||||
v: string | number
|
v: string | number
|
||||||
}
|
}
|
||||||
export function either4(input: string | number | boolean | Obj): number
|
export function either4(input: string | number | boolean | Obj): number
|
||||||
export enum Kind { Dog = 0, Cat = 1, Duck = 2 }
|
export enum Kind {
|
||||||
export enum CustomNumEnum { One = 1, Two = 2, Three = 3, Four = 4, Six = 6, Eight = 8, Nine = 9, Ten = 10 }
|
Dog = 0,
|
||||||
|
Cat = 1,
|
||||||
|
Duck = 2,
|
||||||
|
}
|
||||||
|
export enum CustomNumEnum {
|
||||||
|
One = 1,
|
||||||
|
Two = 2,
|
||||||
|
Three = 3,
|
||||||
|
Four = 4,
|
||||||
|
Six = 6,
|
||||||
|
Eight = 8,
|
||||||
|
Nine = 9,
|
||||||
|
Ten = 10,
|
||||||
|
}
|
||||||
export function enumToI32(e: CustomNumEnum): number
|
export function enumToI32(e: CustomNumEnum): number
|
||||||
export function throwError(): void
|
export function throwError(): void
|
||||||
export function mapOption(val: number | null): number | null
|
export function mapOption(val: number | null): number | null
|
||||||
|
@ -24,6 +39,9 @@ export function add(a: number, b: number): number
|
||||||
export function fibonacci(n: number): number
|
export function fibonacci(n: number): number
|
||||||
export function listObjKeys(obj: object): Array<string>
|
export function listObjKeys(obj: object): Array<string>
|
||||||
export function createObj(): object
|
export function createObj(): object
|
||||||
|
export function getGlobal(): typeof global
|
||||||
|
export function getUndefined(): JsUndefined
|
||||||
|
export function getNull(): JsNull
|
||||||
export function asyncPlus100(p: Promise<number>): Promise<number>
|
export function asyncPlus100(p: Promise<number>): Promise<number>
|
||||||
interface PackageJson {
|
interface PackageJson {
|
||||||
name: string
|
name: string
|
||||||
|
@ -38,7 +56,11 @@ export function concatStr(s: string): string
|
||||||
export function concatUtf16(s: string): string
|
export function concatUtf16(s: string): string
|
||||||
export function concatLatin1(s: string): string
|
export function concatLatin1(s: string): string
|
||||||
export function withoutAbortController(a: number, b: number): Promise<number>
|
export function withoutAbortController(a: number, b: number): Promise<number>
|
||||||
export function withAbortController(a: number, b: number, signal: AbortSignal): Promise<number>
|
export function withAbortController(
|
||||||
|
a: number,
|
||||||
|
b: number,
|
||||||
|
signal: AbortSignal,
|
||||||
|
): Promise<number>
|
||||||
export function callThreadsafeFunction(callback: (...args: any[]) => any): void
|
export function callThreadsafeFunction(callback: (...args: any[]) => any): void
|
||||||
export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void
|
export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void
|
||||||
export function getBuffer(): Buffer
|
export function getBuffer(): Buffer
|
||||||
|
@ -52,14 +74,10 @@ export class Animal {
|
||||||
static getDogKind(): Kind
|
static getDogKind(): Kind
|
||||||
}
|
}
|
||||||
export class Blake2BHasher {
|
export class Blake2BHasher {
|
||||||
|
|
||||||
static withKey(key: Blake2bKey): Blake2BHasher
|
static withKey(key: Blake2bKey): Blake2BHasher
|
||||||
}
|
}
|
||||||
export class Blake2BKey {
|
export class Blake2BKey {}
|
||||||
|
|
||||||
}
|
|
||||||
export class Context {
|
export class Context {
|
||||||
|
|
||||||
constructor()
|
constructor()
|
||||||
static withData(data: string): Context
|
static withData(data: string): Context
|
||||||
method(): string
|
method(): string
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use napi::bindgen_prelude::*;
|
use napi::{bindgen_prelude::*, JsGlobal, JsNull, JsUndefined};
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
fn list_obj_keys(obj: Object) -> Vec<String> {
|
fn list_obj_keys(obj: Object) -> Vec<String> {
|
||||||
|
@ -12,3 +12,18 @@ fn create_obj(env: Env) -> Object {
|
||||||
|
|
||||||
obj
|
obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
fn get_global(env: Env) -> Result<JsGlobal> {
|
||||||
|
env.get_global()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
fn get_undefined(env: Env) -> Result<JsUndefined> {
|
||||||
|
env.get_undefined()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
fn get_null(env: Env) -> Result<JsNull> {
|
||||||
|
env.get_null()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue