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, 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() } }