Fire an event and get the result
(&self, event: &HookEvent)
| 288 | |
| 289 | /// Fire an event and get the result |
| 290 | pub async fn fire(&self, event: &HookEvent) -> HookResult { |
| 291 | // Send event to channel if available |
| 292 | if let Some(ref tx) = self.event_tx { |
| 293 | let _ = tx.send(event.clone()).await; |
| 294 | } |
| 295 | |
| 296 | // Get matching hooks |
| 297 | let matching_hooks = self.matching_hooks(event); |
| 298 | |
| 299 | if matching_hooks.is_empty() { |
| 300 | return HookResult::continue_(); |
| 301 | } |
| 302 | |
| 303 | // Execute each hook |
| 304 | let mut last_modified: Option<serde_json::Value> = None; |
| 305 | for hook in matching_hooks { |
| 306 | let result = self.execute_hook(&hook, event).await; |
| 307 | |
| 308 | match result { |
| 309 | HookResult::Continue(modified) => { |
| 310 | // Track the last modification — continue to subsequent hooks |
| 311 | if modified.is_some() { |
| 312 | last_modified = modified; |
| 313 | } |
| 314 | } |
| 315 | HookResult::Block(reason) => { |
| 316 | return HookResult::Block(reason); |
| 317 | } |
| 318 | HookResult::Retry(delay) => { |
| 319 | return HookResult::Retry(delay); |
| 320 | } |
| 321 | HookResult::Skip => { |
| 322 | return HookResult::Continue(None); |
| 323 | } |
| 324 | HookResult::Escalate { reason, target } => { |
| 325 | return HookResult::Escalate { reason, target }; |
| 326 | } |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | HookResult::Continue(last_modified) |
| 331 | } |
| 332 | |
| 333 | /// Execute a single hook |
| 334 | async fn execute_hook(&self, hook: &Hook, event: &HookEvent) -> HookResult { |