use anyhow::{Result, bail};
use cel_cxx::Activation;
use wasmtime::Store;
use crate::wasm::{
Host,
bindgen::{
Event as WasmEvent,
witmproxy::plugin::capabilities::{CapabilityKind, EventKind},
},
};
pub mod connect;
pub mod content;
pub mod request;
pub mod response;
pub mod timer;
pub trait Event: Send {
fn capability(&self) -> CapabilityKind;
fn kind(&self) -> EventKind {
match self.capability() {
CapabilityKind::HandleEvent(kind) => kind,
_ => panic!("Event capability must be of HandleEvent kind"),
}
}
fn into_event_data(self: Box<Self>, store: &mut Store<Host>) -> Result<WasmEvent>;
fn register_cel_env<'a>(env: cel_cxx::EnvBuilder<'a>) -> Result<cel_cxx::EnvBuilder<'a>>
where
Self: Sized;
fn bind_cel_activation<'a>(&'a self, a: Activation<'a>) -> Option<Activation<'a>>;
}
macro_rules! ensure_matches {
($expr:expr, $pat:pat $(if $guard:expr)? $(,)?) => {
match $expr {
$pat $(if $guard)? => Ok(()),
_ => Err(anyhow::anyhow!(
"pattern did not match, expected to find one of: {}",
stringify!($pat)
)),
}
};
}
impl EventKind {
pub fn validate_output(&self, event_data: &WasmEvent) -> Result<()> {
match self {
EventKind::Request => {
ensure_matches!(event_data, WasmEvent::Request(_) | WasmEvent::Response(_))
}
EventKind::Response => ensure_matches!(event_data, WasmEvent::Response(_)),
EventKind::Connect => {
bail!("Connect events do not return Event (no guest handling)")
}
EventKind::InboundContent => ensure_matches!(event_data, WasmEvent::InboundContent(_)),
EventKind::Timer => ensure_matches!(event_data, WasmEvent::Timer(_)),
}
}
}
impl std::fmt::Display for EventKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EventKind::Request => write!(f, "request"),
EventKind::Response => write!(f, "response"),
EventKind::Connect => write!(f, "connect"),
EventKind::InboundContent => write!(f, "inbound_content"),
EventKind::Timer => write!(f, "timer"),
}
}
}