use tokio::sync::mpsc;
use tokio::sync::oneshot;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum HostResolved {
Url(String),
External(String),
}
#[derive(Debug, Clone)]
pub struct HostModule {
pub code: String,
pub module_type: HostModuleType,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HostModuleType {
JavaScript,
Json,
}
pub enum HostRequest {
Resolve {
importer: String,
specifier: String,
reply: std::sync::mpsc::Sender<Result<Option<HostResolved>, String>>,
},
Load {
specifier: String,
reply: oneshot::Sender<Result<Option<HostModule>, String>>,
},
}
pub type HostRequests = mpsc::UnboundedReceiver<HostRequest>;
#[derive(Clone)]
pub struct ModuleHost {
tx: mpsc::UnboundedSender<HostRequest>,
}
impl ModuleHost {
pub fn channel() -> (ModuleHost, HostRequests) {
let (tx, rx) = mpsc::unbounded_channel();
(ModuleHost { tx }, rx)
}
pub(crate) fn resolve_blocking(
&self,
importer: &str,
specifier: &str,
) -> Result<Option<HostResolved>, String> {
let (reply, reply_rx) = std::sync::mpsc::channel();
self.tx
.send(HostRequest::Resolve {
importer: importer.to_string(),
specifier: specifier.to_string(),
reply,
})
.map_err(|_| "the module host is gone".to_string())?;
reply_rx
.recv()
.map_err(|_| "the module host dropped the resolve reply".to_string())?
}
pub(crate) async fn load(&self, specifier: &str) -> Result<Option<HostModule>, String> {
let (reply, reply_rx) = oneshot::channel();
self.tx
.send(HostRequest::Load {
specifier: specifier.to_string(),
reply,
})
.map_err(|_| "the module host is gone".to_string())?;
reply_rx
.await
.map_err(|_| "the module host dropped the load reply".to_string())?
}
}