oxihuman_core/
dispatch_table.rs1#![allow(dead_code)]
4
5use std::collections::HashMap;
6
7#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct DispatchTable {
11 handlers: HashMap<String, HandlerEntry>,
12 next_id: u64,
13}
14
15#[allow(dead_code)]
16#[derive(Debug, Clone)]
17pub struct HandlerEntry {
18 pub id: u64,
19 pub name: String,
20 pub priority: i32,
21 pub enabled: bool,
22}
23
24impl Default for DispatchTable {
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30#[allow(dead_code)]
31impl DispatchTable {
32 pub fn new() -> Self {
33 Self {
34 handlers: HashMap::new(),
35 next_id: 1,
36 }
37 }
38
39 pub fn register(&mut self, key: &str, priority: i32) -> u64 {
40 let id = self.next_id;
41 self.next_id += 1;
42 self.handlers.insert(
43 key.to_string(),
44 HandlerEntry {
45 id,
46 name: key.to_string(),
47 priority,
48 enabled: true,
49 },
50 );
51 id
52 }
53
54 pub fn unregister(&mut self, key: &str) -> bool {
55 self.handlers.remove(key).is_some()
56 }
57
58 pub fn lookup(&self, key: &str) -> Option<u64> {
59 self.handlers.get(key).filter(|h| h.enabled).map(|h| h.id)
60 }
61
62 pub fn contains(&self, key: &str) -> bool {
63 self.handlers.contains_key(key)
64 }
65
66 pub fn set_enabled(&mut self, key: &str, enabled: bool) -> bool {
67 if let Some(h) = self.handlers.get_mut(key) {
68 h.enabled = enabled;
69 true
70 } else {
71 false
72 }
73 }
74
75 pub fn is_enabled(&self, key: &str) -> bool {
76 self.handlers.get(key).is_some_and(|h| h.enabled)
77 }
78
79 pub fn count(&self) -> usize {
80 self.handlers.len()
81 }
82
83 pub fn enabled_count(&self) -> usize {
84 self.handlers.values().filter(|h| h.enabled).count()
85 }
86
87 pub fn keys(&self) -> Vec<&str> {
88 self.handlers.keys().map(|k| k.as_str()).collect()
89 }
90
91 pub fn by_priority(&self) -> Vec<&HandlerEntry> {
92 let mut entries: Vec<&HandlerEntry> = self.handlers.values().collect();
93 entries.sort_by(|a, b| b.priority.cmp(&a.priority));
94 entries
95 }
96
97 pub fn clear(&mut self) {
98 self.handlers.clear();
99 }
100
101 pub fn get_entry(&self, key: &str) -> Option<&HandlerEntry> {
102 self.handlers.get(key)
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn test_new() {
112 let dt = DispatchTable::new();
113 assert_eq!(dt.count(), 0);
114 }
115
116 #[test]
117 fn test_register_and_lookup() {
118 let mut dt = DispatchTable::new();
119 let id = dt.register("click", 0);
120 assert_eq!(dt.lookup("click"), Some(id));
121 }
122
123 #[test]
124 fn test_unregister() {
125 let mut dt = DispatchTable::new();
126 dt.register("click", 0);
127 assert!(dt.unregister("click"));
128 assert!(!dt.contains("click"));
129 }
130
131 #[test]
132 fn test_disable() {
133 let mut dt = DispatchTable::new();
134 dt.register("click", 0);
135 dt.set_enabled("click", false);
136 assert!(dt.lookup("click").is_none());
137 assert!(!dt.is_enabled("click"));
138 }
139
140 #[test]
141 fn test_contains() {
142 let mut dt = DispatchTable::new();
143 dt.register("a", 0);
144 assert!(dt.contains("a"));
145 assert!(!dt.contains("b"));
146 }
147
148 #[test]
149 fn test_by_priority() {
150 let mut dt = DispatchTable::new();
151 dt.register("low", 1);
152 dt.register("high", 10);
153 dt.register("mid", 5);
154 let sorted = dt.by_priority();
155 assert_eq!(sorted[0].name, "high");
156 }
157
158 #[test]
159 fn test_enabled_count() {
160 let mut dt = DispatchTable::new();
161 dt.register("a", 0);
162 dt.register("b", 0);
163 dt.set_enabled("b", false);
164 assert_eq!(dt.enabled_count(), 1);
165 }
166
167 #[test]
168 fn test_clear() {
169 let mut dt = DispatchTable::new();
170 dt.register("a", 0);
171 dt.clear();
172 assert_eq!(dt.count(), 0);
173 }
174
175 #[test]
176 fn test_unique_ids() {
177 let mut dt = DispatchTable::new();
178 let id1 = dt.register("a", 0);
179 let id2 = dt.register("b", 0);
180 assert_ne!(id1, id2);
181 }
182
183 #[test]
184 fn test_get_entry() {
185 let mut dt = DispatchTable::new();
186 dt.register("x", 42);
187 let entry = dt.get_entry("x").expect("should succeed");
188 assert_eq!(entry.priority, 42);
189 }
190}