saorsa_agent/extension/
keybinding_registry.rs1use crate::error::{Result, SaorsaAgentError};
4use std::collections::HashMap;
5use std::sync::Arc;
6
7pub type KeybindingHandler = Arc<dyn Fn() -> Result<()> + Send + Sync>;
9
10pub struct KeybindingDefinition {
12 pub key: String,
14 pub description: String,
16 pub handler: KeybindingHandler,
18}
19
20impl KeybindingDefinition {
21 pub fn new(key: String, description: String, handler: KeybindingHandler) -> Self {
23 Self {
24 key,
25 description,
26 handler,
27 }
28 }
29}
30
31pub struct KeybindingRegistry {
33 keybindings: HashMap<String, KeybindingDefinition>,
34}
35
36impl KeybindingRegistry {
37 pub fn new() -> Self {
39 Self {
40 keybindings: HashMap::new(),
41 }
42 }
43
44 pub fn register_keybinding(&mut self, def: KeybindingDefinition) -> Result<()> {
48 if self.keybindings.contains_key(&def.key) {
49 return Err(SaorsaAgentError::Extension(format!(
50 "keybinding '{}' is already registered",
51 def.key
52 )));
53 }
54 self.keybindings.insert(def.key.clone(), def);
55 Ok(())
56 }
57
58 pub fn unregister_keybinding(&mut self, key: &str) -> Result<()> {
62 self.keybindings.remove(key).ok_or_else(|| {
63 SaorsaAgentError::Extension(format!("keybinding '{}' not found", key))
64 })?;
65 Ok(())
66 }
67
68 pub fn get_keybinding(&self, key: &str) -> Option<&KeybindingDefinition> {
70 self.keybindings.get(key)
71 }
72
73 pub fn list_keybindings(&self) -> Vec<&KeybindingDefinition> {
75 self.keybindings.values().collect()
76 }
77
78 pub fn execute_keybinding(&self, key: &str) -> Result<()> {
82 let def = self.keybindings.get(key).ok_or_else(|| {
83 SaorsaAgentError::Extension(format!("keybinding '{}' not found", key))
84 })?;
85 (def.handler)()
86 }
87}
88
89impl Default for KeybindingRegistry {
90 fn default() -> Self {
91 Self::new()
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 fn test_handler() -> Result<()> {
100 Ok(())
101 }
102
103 #[test]
104 fn register_keybinding() {
105 let mut registry = KeybindingRegistry::new();
106 let def = KeybindingDefinition::new(
107 "ctrl+k".to_string(),
108 "Test keybinding".to_string(),
109 Arc::new(test_handler),
110 );
111 let result = registry.register_keybinding(def);
112 assert!(result.is_ok());
113 assert!(registry.get_keybinding("ctrl+k").is_some());
114 }
115
116 #[test]
117 fn duplicate_keybinding_fails() {
118 let mut registry = KeybindingRegistry::new();
119 let def1 = KeybindingDefinition::new(
120 "ctrl+k".to_string(),
121 "Test 1".to_string(),
122 Arc::new(test_handler),
123 );
124 let def2 = KeybindingDefinition::new(
125 "ctrl+k".to_string(),
126 "Test 2".to_string(),
127 Arc::new(test_handler),
128 );
129 assert!(registry.register_keybinding(def1).is_ok());
130 let result = registry.register_keybinding(def2);
131 assert!(result.is_err());
132 match result {
133 Err(SaorsaAgentError::Extension(msg)) => {
134 assert!(msg.contains("already registered"));
135 }
136 _ => unreachable!(),
137 }
138 }
139
140 #[test]
141 fn unregister_keybinding() {
142 let mut registry = KeybindingRegistry::new();
143 let def = KeybindingDefinition::new(
144 "ctrl+k".to_string(),
145 "Test".to_string(),
146 Arc::new(test_handler),
147 );
148 assert!(registry.register_keybinding(def).is_ok());
149 assert!(registry.unregister_keybinding("ctrl+k").is_ok());
150 assert!(registry.get_keybinding("ctrl+k").is_none());
151 }
152
153 #[test]
154 fn unregister_nonexistent_fails() {
155 let mut registry = KeybindingRegistry::new();
156 let result = registry.unregister_keybinding("nonexistent");
157 assert!(result.is_err());
158 match result {
159 Err(SaorsaAgentError::Extension(msg)) => {
160 assert!(msg.contains("not found"));
161 }
162 _ => unreachable!(),
163 }
164 }
165
166 #[test]
167 fn list_keybindings() {
168 let mut registry = KeybindingRegistry::new();
169 let def1 = KeybindingDefinition::new(
170 "ctrl+k".to_string(),
171 "Test 1".to_string(),
172 Arc::new(test_handler),
173 );
174 let def2 = KeybindingDefinition::new(
175 "alt+p".to_string(),
176 "Test 2".to_string(),
177 Arc::new(test_handler),
178 );
179 assert!(registry.register_keybinding(def1).is_ok());
180 assert!(registry.register_keybinding(def2).is_ok());
181 let list = registry.list_keybindings();
182 assert_eq!(list.len(), 2);
183 }
184
185 #[test]
186 fn execute_keybinding() {
187 let mut registry = KeybindingRegistry::new();
188 let def = KeybindingDefinition::new(
189 "ctrl+k".to_string(),
190 "Test".to_string(),
191 Arc::new(test_handler),
192 );
193 assert!(registry.register_keybinding(def).is_ok());
194 let result = registry.execute_keybinding("ctrl+k");
195 assert!(result.is_ok());
196 }
197
198 #[test]
199 fn execute_nonexistent_fails() {
200 let registry = KeybindingRegistry::new();
201 let result = registry.execute_keybinding("nonexistent");
202 assert!(result.is_err());
203 match result {
204 Err(SaorsaAgentError::Extension(msg)) => {
205 assert!(msg.contains("not found"));
206 }
207 _ => unreachable!(),
208 }
209 }
210}