macro_rules! class_wrapper {
($class_name:ident($($argument_name:ident: $argument_type:ty),+)) => {
crate::vscode_sys::macros::class_wrapper_inner! {
::napi::bindgen_prelude::FnArgs<($($argument_type,)*)>,
::napi::bindgen_prelude::FnArgs::from(($($argument_name,)*)),
$class_name($($argument_name: $argument_type),+)
}
};
}
macro_rules! class_wrapper_empty {
($class_name:ident) => {
crate::vscode_sys::macros::class_wrapper_inner! {
(),
(),
$class_name()
}
};
}
macro_rules! class_wrapper_inner {
($constructor_args_type:ty, $constructor_args_initializer:expr, $class_name:ident($($argument_name:ident: $argument_type:ty),*)) => {
pub struct $class_name<'env> {
pub inner: ::napi::bindgen_prelude::Object<'env>,
}
impl<'env> $class_name<'env> {
pub fn new(
env: &napi::Env,
$($argument_name: $argument_type),*
) -> Result<Self, ::napi::Error> {
let vscode_object = VscodeContext::vscode(env)?;
let constructor_prototype: ::napi::bindgen_prelude::Function<
'env,
$constructor_args_type,
::napi::bindgen_prelude::Object<'env>,
> = vscode_object.get_named_property(stringify!($class_name))?;
let class_result: ::napi::bindgen_prelude::Unknown =
constructor_prototype.new_instance($constructor_args_initializer)?;
let class_object = ::napi::bindgen_prelude::Object::from_unknown(class_result)?;
Ok(Self {
inner: class_object,
})
}
}
impl<'env> ToNapiValue for &$class_name<'env> {
unsafe fn to_napi_value(env: napi_env, val: Self) -> Result<napi_value, napi::Error> {
unsafe { bindgen_prelude::Object::to_napi_value(env, val.inner) }
}
}
impl<'env> ToNapiValue for $class_name<'env> {
unsafe fn to_napi_value(env: napi_env, val: Self) -> Result<napi_value, napi::Error> {
unsafe { bindgen_prelude::Object::to_napi_value(env, val.inner) }
}
}
impl<'env> FromNapiValue for $class_name<'env> {
unsafe fn from_napi_value(
raw_env: napi_sys::napi_env,
napi_val: napi_sys::napi_value,
) -> Result<Self, napi::Error> {
let inner = unsafe { bindgen_prelude::Object::from_napi_value(raw_env, napi_val) }?;
Ok(Self { inner })
}
}
impl<'env> TypeName for $class_name<'env> {
fn type_name() -> &'static str {
bindgen_prelude::Object::type_name()
}
fn value_type() -> napi::ValueType {
bindgen_prelude::Object::value_type()
}
}
impl<'env> ValidateNapiValue for $class_name<'env> {
unsafe fn validate(
raw_env: napi_sys::napi_env,
raw_class: napi_sys::napi_value,
) -> Result<napi_sys::napi_value, napi::Error> {
let class = match unsafe { <bindgen_prelude::Object as ValidateNapiValue>::validate(raw_env, raw_class) } {
Ok(_validated_class) => bindgen_prelude::Object::from_raw(raw_env, raw_class),
Err(mut error) => {
error.reason = format!("Invalid type for {}: {}", stringify!($class_name), error.reason);
return Err(error);
}
};
let env = napi::Env::from_raw(raw_env);
let vscode_object = VscodeContext::vscode(&env)?;
let constructor: bindgen_prelude::Function<$constructor_args_type, bindgen_prelude::Object> = vscode_object.get_named_property(stringify!($class_name))?;
if !class.instanceof(constructor)? {
return Err(napi::Error::from_reason(
concat!("Object is not an instance of ", stringify!($class_name)),
));
}
Ok(raw_class)
}
}
};
}
pub(crate) use class_wrapper;
pub(crate) use class_wrapper_empty;
pub(crate) use class_wrapper_inner;