mirror of
https://github.com/lexmount/moli.git
synced 2026-09-28 16:01:39 +00:00
138 lines
4.4 KiB
Rust
138 lines
4.4 KiB
Rust
use crate::{__private, BindError, WebApiObject, v8};
|
|
|
|
/// Binds a constructor-backed Web API V8 function template.
|
|
///
|
|
/// Implementations are generated by `#[derive(WebApiFunctionTemplate)]`. The
|
|
/// generated binding creates a `FunctionTemplate`, sets its class name, and
|
|
/// installs declared static methods and constants onto the constructor template
|
|
/// and declared instance methods, intrinsic data properties, and constants onto
|
|
/// the prototype template. This is separate from `WebApiObjectDeclaration`
|
|
/// because template installation happens before constructor/prototype objects
|
|
/// exist in a V8 context.
|
|
pub trait WebApiFunctionTemplateDeclaration {
|
|
const NAME: &'static str;
|
|
|
|
fn build<'s>(scope: &mut v8::PinScope<'s, '_, ()>) -> v8::Local<'s, v8::FunctionTemplate>;
|
|
|
|
fn initialize_template<'s>(
|
|
scope: &mut v8::PinScope<'s, '_, ()>,
|
|
template: v8::Local<'s, v8::FunctionTemplate>,
|
|
);
|
|
|
|
fn initialize_prototype_template<'s>(
|
|
scope: &mut v8::PinScope<'s, '_, ()>,
|
|
prototype: v8::Local<'s, v8::ObjectTemplate>,
|
|
);
|
|
}
|
|
|
|
/// Binds a native instance, plain object, or shared initialization fragment.
|
|
///
|
|
/// Implementations are generated by `#[derive(WebApiObject)]`. `initialize`
|
|
/// installs only the fields that are explicitly declared as properties, methods,
|
|
/// hidden properties, private slots, prototype values, or toStringTag values.
|
|
/// `bind_into` additionally applies the role's prototype policy and declared object
|
|
/// tag. `bind` creates a fresh V8 object and then delegates to `bind_into`.
|
|
pub trait WebApiObjectDeclaration<'s> {
|
|
fn initialize(
|
|
&self,
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
object: v8::Local<'s, v8::Object>,
|
|
) -> Result<(), BindError>;
|
|
|
|
fn bind_into(
|
|
&self,
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
object: v8::Local<'s, v8::Object>,
|
|
) -> Result<(), BindError>;
|
|
|
|
fn bind(
|
|
&self,
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
) -> Result<v8::Local<'s, v8::Object>, BindError>;
|
|
}
|
|
|
|
/// Declares the descriptor object returned by native named/indexed property
|
|
/// descriptor interceptors for data properties.
|
|
#[derive(WebApiObject)]
|
|
#[webapi(plain, data_properties, enumerable, no_dynamic_constructor)]
|
|
pub struct DataPropertyDescriptorDeclaration<'scope> {
|
|
value: v8::Local<'scope, v8::Value>,
|
|
enumerable: bool,
|
|
configurable: bool,
|
|
writable: bool,
|
|
}
|
|
|
|
impl<'scope> DataPropertyDescriptorDeclaration<'scope> {
|
|
pub fn new(value: v8::Local<'scope, v8::Value>, writable: bool, enumerable: bool) -> Self {
|
|
Self {
|
|
value,
|
|
enumerable,
|
|
configurable: true,
|
|
writable,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Small builder for plain object literals that are assembled imperatively.
|
|
///
|
|
/// Prefer `#[derive(WebApiObject)]` when the shape is known from a Rust struct.
|
|
/// This helper remains useful for dynamic copies where the property set is only
|
|
/// known at runtime, such as collecting selected fields from another V8 object.
|
|
pub struct ObjectLiteralDeclaration<'s> {
|
|
object: v8::Local<'s, v8::Object>,
|
|
}
|
|
|
|
impl<'s> ObjectLiteralDeclaration<'s> {
|
|
pub fn bind(scope: &mut v8::PinScope<'s, '_>) -> Self {
|
|
Self {
|
|
object: v8::Object::new(scope),
|
|
}
|
|
}
|
|
|
|
pub fn set_value_property(
|
|
&self,
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
name: v8::Local<'s, v8::Name>,
|
|
value: v8::Local<'s, v8::Value>,
|
|
) {
|
|
let _ = self.object.create_data_property(scope, name, value);
|
|
}
|
|
|
|
pub fn set_string_property(
|
|
&self,
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
name: &str,
|
|
value: v8::Local<'s, v8::Value>,
|
|
) {
|
|
if let Some(name) = __private::v8_string(scope, name) {
|
|
self.set_value_property(scope, name.into(), value);
|
|
}
|
|
}
|
|
|
|
pub fn copy_string_property(
|
|
&self,
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
source: v8::Local<'s, v8::Object>,
|
|
name: &str,
|
|
) {
|
|
let Some(name) = __private::v8_string(scope, name) else {
|
|
return;
|
|
};
|
|
if let Some(value) = source.get(scope, name.into()) {
|
|
self.set_value_property(scope, name.into(), value);
|
|
}
|
|
}
|
|
|
|
pub fn as_object(&self) -> v8::Local<'s, v8::Object> {
|
|
self.object
|
|
}
|
|
|
|
pub fn into_object(self) -> v8::Local<'s, v8::Object> {
|
|
self.object
|
|
}
|
|
|
|
pub fn into_value(self) -> v8::Local<'s, v8::Value> {
|
|
self.object.into()
|
|
}
|
|
}
|