mirror of
https://github.com/lexmount/moli.git
synced 2026-09-29 00:01:38 +00:00
124 lines
3.5 KiB
Rust
124 lines
3.5 KiB
Rust
use moli_v8_util::{define_static_symbol_to_string_tag, global_constructor_prototype};
|
|
|
|
use crate::{BindError, WebApiValue, v8};
|
|
|
|
pub fn set_interface_prototype<'s>(
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
object: v8::Local<'s, v8::Object>,
|
|
interface: &'static str,
|
|
) -> bool {
|
|
if interface == "Object" {
|
|
return true;
|
|
}
|
|
if let Some(prototype) = global_constructor_prototype(scope, interface) {
|
|
object
|
|
.set_prototype(scope, prototype.into())
|
|
.unwrap_or(false)
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
pub fn set_required_interface_prototype<'s>(
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
object: v8::Local<'s, v8::Object>,
|
|
interface: &'static str,
|
|
) -> Result<(), BindError> {
|
|
if interface == "Object" {
|
|
return Ok(());
|
|
}
|
|
let prototype = global_constructor_prototype(scope, interface)
|
|
.ok_or_else(|| BindError::new(format!("missing `{interface}` prototype")))?;
|
|
let installed = object
|
|
.set_prototype(scope, prototype.into())
|
|
.unwrap_or(false);
|
|
if !installed {
|
|
return Err(BindError::new(format!(
|
|
"failed to set `{interface}` prototype"
|
|
)));
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn define_to_string_tag(
|
|
scope: &mut v8::PinScope<'_, '_>,
|
|
object: v8::Local<'_, v8::Object>,
|
|
tag: &'static str,
|
|
) {
|
|
define_to_string_tag_with_attributes(scope, object, tag, v8::PropertyAttribute::DONT_ENUM);
|
|
}
|
|
|
|
pub fn define_to_string_tag_with_attributes(
|
|
scope: &mut v8::PinScope<'_, '_>,
|
|
object: v8::Local<'_, v8::Object>,
|
|
tag: &'static str,
|
|
attributes: v8::PropertyAttribute,
|
|
) {
|
|
define_static_symbol_to_string_tag(scope, object, tag, attributes);
|
|
}
|
|
|
|
pub fn set_declared_prototype<'s, V>(
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
object: v8::Local<'s, v8::Object>,
|
|
prototype: &V,
|
|
) -> Result<(), BindError>
|
|
where
|
|
V: WebApiValue<'s> + ?Sized,
|
|
{
|
|
let prototype = prototype
|
|
.to_v8_value(scope)
|
|
.ok_or_else(|| BindError::new("failed to convert declared prototype"))?;
|
|
let prototype = v8::Local::<v8::Object>::try_from(prototype)
|
|
.map_err(|_| BindError::new("declared prototype must be an object"))?;
|
|
let installed = object
|
|
.set_prototype(scope, prototype.into())
|
|
.unwrap_or(false);
|
|
if !installed {
|
|
return Err(BindError::new("failed to set declared prototype"));
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn define_declared_to_string_tag<'s, V>(
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
object: v8::Local<'s, v8::Object>,
|
|
tag: &V,
|
|
) -> Result<(), BindError>
|
|
where
|
|
V: WebApiValue<'s> + ?Sized,
|
|
{
|
|
define_declared_to_string_tag_with_attributes(
|
|
scope,
|
|
object,
|
|
tag,
|
|
v8::PropertyAttribute::DONT_ENUM,
|
|
)
|
|
}
|
|
|
|
pub fn define_declared_to_string_tag_with_attributes<'s, V>(
|
|
scope: &mut v8::PinScope<'s, '_>,
|
|
object: v8::Local<'s, v8::Object>,
|
|
tag: &V,
|
|
attributes: v8::PropertyAttribute,
|
|
) -> Result<(), BindError>
|
|
where
|
|
V: WebApiValue<'s> + ?Sized,
|
|
{
|
|
let tag = tag
|
|
.to_v8_value(scope)
|
|
.ok_or_else(|| BindError::new("failed to convert declared toStringTag"))?;
|
|
let tag = tag
|
|
.to_string(scope)
|
|
.ok_or_else(|| BindError::new("failed to stringify declared toStringTag"))?;
|
|
object
|
|
.define_own_property(
|
|
scope,
|
|
v8::Symbol::get_to_string_tag(scope).into(),
|
|
tag.into(),
|
|
attributes,
|
|
)
|
|
.unwrap_or(false)
|
|
.then_some(())
|
|
.ok_or_else(|| BindError::new("failed to define declared toStringTag"))
|
|
}
|