use super::EventArgs;
pub type EventHandler = Box<dyn Fn(&EventArgs) -> EventResult + Send + Sync>;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum EventResult {
Continue,
Stop,
Modified(Vec<u8>),
}
impl EventResult {
pub fn is_continue(&self) -> bool {
matches!(self, EventResult::Continue)
}
pub fn is_stop(&self) -> bool {
matches!(self, EventResult::Stop)
}
pub fn is_modified(&self) -> bool {
matches!(self, EventResult::Modified(_))
}
pub fn into_modified(self) -> Option<Vec<u8>> {
match self {
EventResult::Modified(data) => Some(data),
_ => None,
}
}
pub fn as_modified(&self) -> Option<&[u8]> {
match self {
EventResult::Modified(data) => Some(data),
_ => None,
}
}
}
pub struct HandlerEntry {
pub id: u64,
pub plugin_name: String,
pub priority: i32,
pub handler: EventHandler,
}
impl HandlerEntry {
pub fn new(
id: u64,
plugin_name: impl Into<String>,
priority: i32,
handler: EventHandler,
) -> Self {
Self {
id,
plugin_name: plugin_name.into(),
priority,
handler,
}
}
pub fn call(&self, args: &EventArgs) -> EventResult {
(self.handler)(args)
}
}
impl std::fmt::Debug for HandlerEntry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("HandlerEntry")
.field("id", &self.id)
.field("plugin_name", &self.plugin_name)
.field("priority", &self.priority)
.field("handler", &"<function>")
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::events::EventType;
#[test]
fn test_event_result_checks() {
assert!(EventResult::Continue.is_continue());
assert!(!EventResult::Continue.is_stop());
assert!(!EventResult::Continue.is_modified());
assert!(EventResult::Stop.is_stop());
assert!(!EventResult::Stop.is_continue());
let modified = EventResult::Modified(vec![1, 2, 3]);
assert!(modified.is_modified());
assert!(!modified.is_stop());
assert_eq!(modified.as_modified(), Some(&[1, 2, 3][..]));
}
#[test]
fn test_event_result_into_modified() {
let result = EventResult::Modified(vec![1, 2, 3]);
assert_eq!(result.into_modified(), Some(vec![1, 2, 3]));
let result = EventResult::Continue;
assert_eq!(result.into_modified(), None);
}
#[test]
fn test_handler_entry_creation() {
let handler: EventHandler = Box::new(|_| EventResult::Continue);
let entry = HandlerEntry::new(1, "test-plugin", 100, handler);
assert_eq!(entry.id, 1);
assert_eq!(entry.plugin_name, "test-plugin");
assert_eq!(entry.priority, 100);
}
#[test]
fn test_handler_entry_call() {
let handler: EventHandler = Box::new(|args| {
if args.event_type == EventType::Bell {
EventResult::Stop
} else {
EventResult::Continue
}
});
let entry = HandlerEntry::new(1, "test", 0, handler);
let bell_args = EventArgs::new(EventType::Bell);
assert_eq!(entry.call(&bell_args), EventResult::Stop);
let other_args = EventArgs::new(EventType::TabCreated);
assert_eq!(entry.call(&other_args), EventResult::Continue);
}
#[test]
fn test_handler_entry_debug() {
let handler: EventHandler = Box::new(|_| EventResult::Continue);
let entry = HandlerEntry::new(42, "debug-test", 50, handler);
let debug_str = format!("{:?}", entry);
assert!(debug_str.contains("42"));
assert!(debug_str.contains("debug-test"));
assert!(debug_str.contains("50"));
assert!(debug_str.contains("<function>"));
}
}