use super::hook_registry::HookHandler;
use async_trait::async_trait;
use nexo_extensions::{HookResponse, StdioRuntime};
use serde_json::Value;
use std::sync::Arc;
use std::time::Duration;
pub struct ExtensionHook {
plugin_id: String,
runtime: Arc<StdioRuntime>,
timeout: Option<Duration>,
}
impl ExtensionHook {
pub fn new(plugin_id: impl Into<String>, runtime: Arc<StdioRuntime>) -> Self {
Self {
plugin_id: plugin_id.into(),
runtime,
timeout: None,
}
}
pub fn with_timeout(mut self, timeout: Option<Duration>) -> Self {
self.timeout = timeout;
self
}
pub fn plugin_id(&self) -> &str {
&self.plugin_id
}
}
#[async_trait]
impl HookHandler for ExtensionHook {
async fn on_hook(&self, name: &str, event: Value) -> anyhow::Result<HookResponse> {
let method = format!("hooks/{name}");
let raw = self
.runtime
.call_with_timeout(&method, event, self.timeout)
.await
.map_err(|e| anyhow::anyhow!("hook `{name}` on ext `{}`: {e}", self.plugin_id))?;
if raw.is_null() {
return Ok(HookResponse::default());
}
serde_json::from_value::<HookResponse>(raw).map_err(|e| {
anyhow::anyhow!("invalid hook response from ext `{}`: {e}", self.plugin_id)
})
}
}