scarab_plugin_api/events/
handler.rs1use super::EventArgs;
6
7pub type EventHandler = Box<dyn Fn(&EventArgs) -> EventResult + Send + Sync>;
14
15#[derive(Clone, Debug, PartialEq, Eq)]
19pub enum EventResult {
20 Continue,
25
26 Stop,
31
32 Modified(Vec<u8>),
38}
39
40impl EventResult {
41 pub fn is_continue(&self) -> bool {
43 matches!(self, EventResult::Continue)
44 }
45
46 pub fn is_stop(&self) -> bool {
48 matches!(self, EventResult::Stop)
49 }
50
51 pub fn is_modified(&self) -> bool {
53 matches!(self, EventResult::Modified(_))
54 }
55
56 pub fn into_modified(self) -> Option<Vec<u8>> {
58 match self {
59 EventResult::Modified(data) => Some(data),
60 _ => None,
61 }
62 }
63
64 pub fn as_modified(&self) -> Option<&[u8]> {
66 match self {
67 EventResult::Modified(data) => Some(data),
68 _ => None,
69 }
70 }
71}
72
73pub struct HandlerEntry {
77 pub id: u64,
79
80 pub plugin_name: String,
82
83 pub priority: i32,
91
92 pub handler: EventHandler,
94}
95
96impl HandlerEntry {
97 pub fn new(
99 id: u64,
100 plugin_name: impl Into<String>,
101 priority: i32,
102 handler: EventHandler,
103 ) -> Self {
104 Self {
105 id,
106 plugin_name: plugin_name.into(),
107 priority,
108 handler,
109 }
110 }
111
112 pub fn call(&self, args: &EventArgs) -> EventResult {
114 (self.handler)(args)
115 }
116}
117
118impl std::fmt::Debug for HandlerEntry {
119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120 f.debug_struct("HandlerEntry")
121 .field("id", &self.id)
122 .field("plugin_name", &self.plugin_name)
123 .field("priority", &self.priority)
124 .field("handler", &"<function>")
125 .finish()
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use crate::events::EventType;
133
134 #[test]
135 fn test_event_result_checks() {
136 assert!(EventResult::Continue.is_continue());
137 assert!(!EventResult::Continue.is_stop());
138 assert!(!EventResult::Continue.is_modified());
139
140 assert!(EventResult::Stop.is_stop());
141 assert!(!EventResult::Stop.is_continue());
142
143 let modified = EventResult::Modified(vec![1, 2, 3]);
144 assert!(modified.is_modified());
145 assert!(!modified.is_stop());
146 assert_eq!(modified.as_modified(), Some(&[1, 2, 3][..]));
147 }
148
149 #[test]
150 fn test_event_result_into_modified() {
151 let result = EventResult::Modified(vec![1, 2, 3]);
152 assert_eq!(result.into_modified(), Some(vec![1, 2, 3]));
153
154 let result = EventResult::Continue;
155 assert_eq!(result.into_modified(), None);
156 }
157
158 #[test]
159 fn test_handler_entry_creation() {
160 let handler: EventHandler = Box::new(|_| EventResult::Continue);
161 let entry = HandlerEntry::new(1, "test-plugin", 100, handler);
162
163 assert_eq!(entry.id, 1);
164 assert_eq!(entry.plugin_name, "test-plugin");
165 assert_eq!(entry.priority, 100);
166 }
167
168 #[test]
169 fn test_handler_entry_call() {
170 let handler: EventHandler = Box::new(|args| {
171 if args.event_type == EventType::Bell {
172 EventResult::Stop
173 } else {
174 EventResult::Continue
175 }
176 });
177
178 let entry = HandlerEntry::new(1, "test", 0, handler);
179
180 let bell_args = EventArgs::new(EventType::Bell);
181 assert_eq!(entry.call(&bell_args), EventResult::Stop);
182
183 let other_args = EventArgs::new(EventType::TabCreated);
184 assert_eq!(entry.call(&other_args), EventResult::Continue);
185 }
186
187 #[test]
188 fn test_handler_entry_debug() {
189 let handler: EventHandler = Box::new(|_| EventResult::Continue);
190 let entry = HandlerEntry::new(42, "debug-test", 50, handler);
191 let debug_str = format!("{:?}", entry);
192
193 assert!(debug_str.contains("42"));
194 assert!(debug_str.contains("debug-test"));
195 assert!(debug_str.contains("50"));
196 assert!(debug_str.contains("<function>"));
197 }
198}