use crate::{DefaultLogger, Logger};
use boa_engine::realm::Realm;
use boa_engine::{Context, JsResult};
use std::fmt::Debug;
pub trait RuntimeExtension: Debug {
fn register(self, realm: Option<Realm>, context: &mut Context) -> JsResult<()>;
}
#[derive(Copy, Clone, Debug)]
pub struct TimeoutExtension;
impl RuntimeExtension for TimeoutExtension {
fn register(self, _realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
crate::interval::register(context)
}
}
#[derive(Copy, Clone, Debug)]
pub struct MicrotaskExtension;
impl RuntimeExtension for MicrotaskExtension {
fn register(self, realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
crate::microtask::register(realm, context)
}
}
#[derive(Copy, Clone, Debug)]
pub struct EncodingExtension;
impl RuntimeExtension for EncodingExtension {
fn register(self, realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
crate::text::register(realm, context)?;
Ok(())
}
}
#[derive(Copy, Clone, Debug)]
pub struct StructuredCloneExtension;
impl RuntimeExtension for StructuredCloneExtension {
fn register(self, realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
crate::clone::register(realm, context)
}
}
#[cfg(feature = "url")]
#[derive(Copy, Clone, Debug)]
pub struct UrlExtension;
#[cfg(feature = "url")]
impl RuntimeExtension for UrlExtension {
fn register(self, realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
crate::url::Url::register(realm, context)
}
}
#[derive(Debug)]
pub struct ConsoleExtension<L: Logger>(pub L);
impl Default for ConsoleExtension<DefaultLogger> {
fn default() -> Self {
ConsoleExtension(DefaultLogger)
}
}
impl<L: Logger + Debug + 'static> RuntimeExtension for ConsoleExtension<L> {
fn register(self, _realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
crate::console::Console::register_with_logger(self.0, context)
}
}
#[cfg(feature = "fetch")]
#[derive(Debug)]
pub struct FetchExtension<F: crate::fetch::Fetcher>(pub F);
#[cfg(feature = "fetch")]
impl<F: crate::fetch::Fetcher + Debug + 'static> RuntimeExtension for FetchExtension<F> {
fn register(self, realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
crate::fetch::register(self.0, realm, context)
}
}
#[derive(Debug)]
pub struct PostMessageExtension<S: crate::message::MessageSender>(pub S);
impl<S: crate::message::MessageSender + Debug + 'static> RuntimeExtension
for PostMessageExtension<S>
{
fn register(self, realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
crate::message::register(self.0, realm, context)
}
}
macro_rules! decl_runtime_ext_tuple {
($first_name: ident : $first_type: ident) => {
impl<$first_type: RuntimeExtension> RuntimeExtension for ($first_type,) {
fn register(self, realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
RuntimeExtension::register(self.0, realm.clone(), context)?;
Ok(())
}
}
};
($first_name: ident : $first_type: ident, $($name: ident : $type: ident),*) => {
impl<$first_type: RuntimeExtension, $($type: RuntimeExtension),*> RuntimeExtension for ($first_type, $($type),*) {
fn register(self, realm: Option<Realm>, context: &mut Context) -> JsResult<()> {
let ($first_name, $($name),*) = self;
RuntimeExtension::register($first_name, realm.clone(), context)?;
$( RuntimeExtension::register($name, realm.clone(), context)?; )*
Ok(())
}
}
decl_runtime_ext_tuple!($($name: $type),*);
};
}
decl_runtime_ext_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L);