use crate::{bindgen_prelude::*, check_status, sys, Result}; use std::{ffi::c_void, ptr}; pub struct CallbackInfo { env: sys::napi_env, this: sys::napi_value, args: [sys::napi_value; N], } impl CallbackInfo { pub fn new( env: sys::napi_env, callback_info: sys::napi_callback_info, required_argc: Option, ) -> Result { let mut this = ptr::null_mut(); let mut args = [ptr::null_mut(); N]; let mut argc = N; unsafe { check_status!( sys::napi_get_cb_info( env, callback_info, &mut argc, args.as_mut_ptr(), &mut this, ptr::null_mut(), ), "Failed to initialize napi function call." )?; }; if let Some(required_argc) = required_argc { if required_argc > argc { return Err(Error::new( Status::InvalidArg, format!( "{} arguments required by received {}.", required_argc, &argc ), )); } } Ok(Self { env, this, args }) } pub fn get_arg(&self, index: usize) -> sys::napi_value { self.args[index] } pub fn this(&self) -> sys::napi_value { self.this } pub fn construct(&self, js_name: &str, obj: T) -> Result { let obj = Box::new(obj); let this = self.this(); unsafe { check_status!( sys::napi_wrap( self.env, this, Box::into_raw(obj) as *mut std::ffi::c_void, Some(raw_finalize_unchecked::), ptr::null_mut(), &mut std::ptr::null_mut() ), "Failed to initialize class `{}`", js_name, )?; }; Ok(this) } pub fn unwrap_borrow_mut(&mut self) -> Result<&'static mut T> where T: FromNapiMutRef + TypeName, { let mut wrapped_val: *mut c_void = std::ptr::null_mut(); unsafe { check_status!( sys::napi_unwrap(self.env, self.this, &mut wrapped_val), "Failed to unwrap exclusive reference of `{}` type from napi value", T::type_name(), )?; Ok(&mut *(wrapped_val as *mut T)) } } pub fn unwrap_borrow(&mut self) -> Result<&'static T> where T: FromNapiRef + TypeName, { let mut wrapped_val: *mut c_void = std::ptr::null_mut(); unsafe { check_status!( sys::napi_unwrap(self.env, self.this, &mut wrapped_val), "Failed to unwrap shared reference of `{}` type from napi value", T::type_name(), )?; Ok(&*(wrapped_val as *const T)) } } }