feat(napi): with_value
method on Property
This commit is contained in:
parent
ed12bd76bd
commit
dfd213a1ee
9 changed files with 86 additions and 5 deletions
|
@ -211,6 +211,38 @@ pub fn get_js_function(raw_fn: ExportRegisterCallback) -> Result<JsFunction> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Get `C Callback` from defined Rust `fn`
|
||||
/// ```rust
|
||||
/// #[napi]
|
||||
/// fn some_fn() -> u32 {
|
||||
/// 1
|
||||
/// }
|
||||
///
|
||||
/// #[napi]
|
||||
/// fn create_obj(env: Env) -> Result<JsObject> {
|
||||
/// let mut obj = env.create_object()?;
|
||||
/// obj.define_property(&[Property::new("getter")?.with_getter(get_c_callback(some_fn_js_function)?)])?;
|
||||
/// Ok(obj)
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ```js
|
||||
/// console.log(createObj().getter) // 1
|
||||
/// ```
|
||||
///
|
||||
pub fn get_c_callback(raw_fn: ExportRegisterCallback) -> Result<crate::Callback> {
|
||||
FN_REGISTER_MAP
|
||||
.borrow_mut()
|
||||
.get(&raw_fn)
|
||||
.and_then(|(_env, cb, _name)| *cb)
|
||||
.ok_or_else(|| {
|
||||
crate::Error::new(
|
||||
crate::Status::InvalidArg,
|
||||
"JavaScript function does not exists".to_owned(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn napi_register_module_v1(
|
||||
env: sys::napi_env,
|
||||
|
|
|
@ -31,7 +31,7 @@ use serde::Serialize;
|
|||
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||
use std::future::Future;
|
||||
|
||||
pub type Callback = extern "C" fn(sys::napi_env, sys::napi_callback_info) -> sys::napi_value;
|
||||
pub type Callback = unsafe extern "C" fn(sys::napi_env, sys::napi_callback_info) -> sys::napi_value;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
/// `Env` is used to represent a context that the underlying N-API implementation can use to persist VM-specific state.
|
||||
|
|
|
@ -2,18 +2,33 @@ use std::convert::From;
|
|||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
use crate::{sys, Callback, Result};
|
||||
use crate::{sys, Callback, NapiRaw, Result};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
#[derive(Clone)]
|
||||
pub struct Property {
|
||||
pub name: CString,
|
||||
getter: sys::napi_callback,
|
||||
setter: sys::napi_callback,
|
||||
method: sys::napi_callback,
|
||||
attrs: PropertyAttributes,
|
||||
value: sys::napi_value,
|
||||
pub(crate) is_ctor: bool,
|
||||
}
|
||||
|
||||
impl Default for Property {
|
||||
fn default() -> Self {
|
||||
Property {
|
||||
name: Default::default(),
|
||||
getter: Default::default(),
|
||||
setter: Default::default(),
|
||||
method: Default::default(),
|
||||
attrs: Default::default(),
|
||||
value: ptr::null_mut(),
|
||||
is_ctor: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(i32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum PropertyAttributes {
|
||||
|
@ -75,6 +90,11 @@ impl Property {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_value<T: NapiRaw>(mut self, value: &T) -> Self {
|
||||
self.value = unsafe { T::raw(value) };
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn raw(&self) -> sys::napi_property_descriptor {
|
||||
sys::napi_property_descriptor {
|
||||
utf8name: self.name.as_ptr(),
|
||||
|
@ -82,7 +102,7 @@ impl Property {
|
|||
method: self.method,
|
||||
getter: self.getter,
|
||||
setter: self.setter,
|
||||
value: ptr::null_mut(),
|
||||
value: self.value,
|
||||
attributes: self.attrs.into(),
|
||||
data: ptr::null_mut(),
|
||||
}
|
||||
|
|
|
@ -112,6 +112,8 @@ Generated by [AVA](https://avajs.dev).
|
|||
typeOverride: object␊
|
||||
typeOverrideOptional?: object␊
|
||||
}␊
|
||||
export function createObjWithProperty(): { value: ArrayBuffer, get getter(): number }␊
|
||||
export function getterFromObj(): number␊
|
||||
export function asyncPlus100(p: Promise<number>): Promise<number>␊
|
||||
/** This is an interface for package.json */␊
|
||||
export interface PackageJson {␊
|
||||
|
|
Binary file not shown.
|
@ -81,6 +81,7 @@ import {
|
|||
getStrFromObject,
|
||||
returnJsFunction,
|
||||
testSerdeRoundtrip,
|
||||
createObjWithProperty,
|
||||
} from '../'
|
||||
|
||||
test('export const', (t) => {
|
||||
|
@ -220,6 +221,12 @@ test('get str from object', (t) => {
|
|||
t.notThrows(() => getStrFromObject())
|
||||
})
|
||||
|
||||
test('create object from Property', (t) => {
|
||||
const obj = createObjWithProperty()
|
||||
t.true(obj.value instanceof ArrayBuffer)
|
||||
t.is(obj.getter, 42)
|
||||
})
|
||||
|
||||
test('global', (t) => {
|
||||
t.is(getGlobal(), global)
|
||||
})
|
||||
|
|
2
examples/napi/index.d.ts
vendored
2
examples/napi/index.d.ts
vendored
|
@ -102,6 +102,8 @@ export interface TsTypeChanged {
|
|||
typeOverride: object
|
||||
typeOverrideOptional?: object
|
||||
}
|
||||
export function createObjWithProperty(): { value: ArrayBuffer, get getter(): number }
|
||||
export function getterFromObj(): number
|
||||
export function asyncPlus100(p: Promise<number>): Promise<number>
|
||||
/** This is an interface for package.json */
|
||||
export interface PackageJson {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate napi_derive;
|
||||
#[macro_use]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use napi::{bindgen_prelude::*, JsGlobal, JsNull, JsUndefined};
|
||||
use napi::{bindgen_prelude::*, JsGlobal, JsNull, JsObject, JsUndefined, Property};
|
||||
|
||||
#[napi]
|
||||
fn list_obj_keys(obj: Object) -> Vec<String> {
|
||||
|
@ -85,3 +85,19 @@ pub struct TsTypeChanged {
|
|||
#[napi(ts_type = "object")]
|
||||
pub type_override_optional: Option<String>,
|
||||
}
|
||||
|
||||
#[napi(ts_return_type = "{ value: ArrayBuffer, get getter(): number }")]
|
||||
pub fn create_obj_with_property(env: Env) -> Result<JsObject> {
|
||||
let mut obj = env.create_object()?;
|
||||
let arraybuffer = env.create_arraybuffer(10)?.into_raw();
|
||||
obj.define_properties(&[
|
||||
Property::new("value")?.with_value(&arraybuffer),
|
||||
Property::new("getter")?.with_getter(get_c_callback(getter_from_obj_js_function)?),
|
||||
])?;
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
#[napi]
|
||||
fn getter_from_obj() -> u32 {
|
||||
42
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue