use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use rquickjs::Ctx;
use crate::modules::{BoxLoader, BoxResolver, ModuleRegistry, RequireHook};
pub trait Extension: Send + Sync {
fn name(&self) -> &str;
fn modules(&self, _registry: &mut ModuleRegistry) -> Result<(), String> {
Ok(())
}
fn loaders(&self) -> Vec<(BoxResolver, BoxLoader)> {
Vec::new()
}
fn require_hook(&self) -> Option<Arc<dyn RequireHook>> {
None
}
fn install(&self, _ctx: &Ctx<'_>) -> rquickjs::Result<()> {
Ok(())
}
fn install_async<'js>(&self, ctx: Ctx<'js>) -> Pin<Box<dyn Future<Output = rquickjs::Result<()>> + 'js>> {
let out = self.install(&ctx);
Box::pin(async move { out })
}
}
pub struct FnExtension<F> {
name: String,
install: F,
}
impl<F> FnExtension<F>
where
F: for<'js> Fn(&Ctx<'js>) -> rquickjs::Result<()> + Send + Sync,
{
pub fn new(name: impl Into<String>, install: F) -> Self {
Self {
name: name.into(),
install,
}
}
}
impl<F> Extension for FnExtension<F>
where
F: for<'js> Fn(&Ctx<'js>) -> rquickjs::Result<()> + Send + Sync,
{
fn name(&self) -> &str {
&self.name
}
fn install(&self, ctx: &Ctx<'_>) -> rquickjs::Result<()> {
(self.install)(ctx)
}
}