1use crate::error::{Error, Result};
6use crate::{Device, Keyboard, Key, Modifiers, Mouse, MouseButton, Gamepad, GamepadButton};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11#[serde(tag = "action", rename_all = "snake_case")]
12pub enum AgentAction {
13 MouseMove { x: i32, y: i32 },
15 MouseClick { button: Option<String> },
16 MouseDoubleClick { button: Option<String> },
17 MouseDown { button: Option<String> },
18 MouseUp { button: Option<String> },
19 MouseScroll { delta: i8 },
20
21 Type { text: String },
23 KeyPress { key: String },
24 KeyDown { key: String },
25 KeyUp { key: String },
26 KeyCombo { modifiers: Vec<String>, key: String },
27
28 GamepadPress { button: String },
30 GamepadRelease { button: String },
31 GamepadLeftStick { x: u8, y: u8 },
32 GamepadRightStick { x: u8, y: u8 },
33 GamepadTriggers { left: u8, right: u8 },
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct AgentResult {
39 pub success: bool,
40 pub error: Option<String>,
41}
42
43impl AgentResult {
44 fn ok() -> Self {
45 Self { success: true, error: None }
46 }
47
48 fn err(msg: impl Into<String>) -> Self {
49 Self { success: false, error: Some(msg.into()) }
50 }
51}
52
53pub struct AgentHID {
55 mouse: Mouse,
56 keyboard: Keyboard,
57 gamepad: Gamepad,
58 mouse_created: bool,
59 keyboard_created: bool,
60 gamepad_created: bool,
61}
62
63impl AgentHID {
64 pub fn new() -> Self {
66 Self {
67 mouse: Mouse::new(),
68 keyboard: Keyboard::new(),
69 gamepad: Gamepad::new(),
70 mouse_created: false,
71 keyboard_created: false,
72 gamepad_created: false,
73 }
74 }
75
76 pub fn execute_json(&mut self, json: &str) -> AgentResult {
78 match serde_json::from_str::<AgentAction>(json) {
79 Ok(action) => self.execute(action),
80 Err(e) => AgentResult::err(format!("Invalid JSON: {}", e)),
81 }
82 }
83
84 pub fn execute(&mut self, action: AgentAction) -> AgentResult {
86 match action {
87 AgentAction::MouseMove { x, y } => self.mouse_move(x, y),
89 AgentAction::MouseClick { button } => self.mouse_click(button),
90 AgentAction::MouseDoubleClick { button } => self.mouse_double_click(button),
91 AgentAction::MouseDown { button } => self.mouse_down(button),
92 AgentAction::MouseUp { button } => self.mouse_up(button),
93 AgentAction::MouseScroll { delta } => self.mouse_scroll(delta),
94
95 AgentAction::Type { text } => self.type_text(&text),
97 AgentAction::KeyPress { key } => self.key_press(&key),
98 AgentAction::KeyDown { key } => self.key_down(&key),
99 AgentAction::KeyUp { key } => self.key_up(&key),
100 AgentAction::KeyCombo { modifiers, key } => self.key_combo(&modifiers, &key),
101
102 AgentAction::GamepadPress { button } => self.gamepad_press(&button),
104 AgentAction::GamepadRelease { button } => self.gamepad_release(&button),
105 AgentAction::GamepadLeftStick { x, y } => self.gamepad_left_stick(x, y),
106 AgentAction::GamepadRightStick { x, y } => self.gamepad_right_stick(x, y),
107 AgentAction::GamepadTriggers { left, right } => self.gamepad_triggers(left, right),
108 }
109 }
110
111 fn ensure_mouse(&mut self) -> Result<()> {
112 if !self.mouse_created {
113 self.mouse.create()?;
114 self.mouse_created = true;
115 }
116 Ok(())
117 }
118
119 fn ensure_keyboard(&mut self) -> Result<()> {
120 if !self.keyboard_created {
121 self.keyboard.create()?;
122 self.keyboard_created = true;
123 }
124 Ok(())
125 }
126
127 fn ensure_gamepad(&mut self) -> Result<()> {
128 if !self.gamepad_created {
129 self.gamepad.create()?;
130 self.gamepad_created = true;
131 }
132 Ok(())
133 }
134
135 fn parse_mouse_button(s: Option<String>) -> MouseButton {
136 match s.as_deref() {
137 Some("right") => MouseButton::RIGHT,
138 Some("middle") => MouseButton::MIDDLE,
139 _ => MouseButton::LEFT,
140 }
141 }
142
143 fn parse_gamepad_button(s: &str) -> Result<GamepadButton> {
144 let btn = match s.to_lowercase().as_str() {
145 "a" => GamepadButton::A,
146 "b" => GamepadButton::B,
147 "x" => GamepadButton::X,
148 "y" => GamepadButton::Y,
149 "lb" | "left_bumper" => GamepadButton::LB,
150 "rb" | "right_bumper" => GamepadButton::RB,
151 "back" | "select" => GamepadButton::BACK,
152 "start" => GamepadButton::START,
153 "guide" | "home" => GamepadButton::GUIDE,
154 "left_stick" | "ls" => GamepadButton::LEFT_STICK,
155 "right_stick" | "rs" => GamepadButton::RIGHT_STICK,
156 "dpad_up" | "up" => GamepadButton::DPAD_UP,
157 "dpad_down" | "down" => GamepadButton::DPAD_DOWN,
158 "dpad_left" | "left" => GamepadButton::DPAD_LEFT,
159 "dpad_right" | "right" => GamepadButton::DPAD_RIGHT,
160 _ => return Err(Error::InvalidAction(format!("Unknown gamepad button: {}", s))),
161 };
162 Ok(btn)
163 }
164
165 fn parse_modifiers(mods: &[String]) -> Modifiers {
166 let mut result = Modifiers::empty();
167 for m in mods {
168 match m.to_lowercase().as_str() {
169 "ctrl" | "control" => result |= Modifiers::CTRL,
170 "shift" => result |= Modifiers::SHIFT,
171 "alt" | "option" => result |= Modifiers::ALT,
172 "cmd" | "command" | "meta" | "gui" | "win" => result |= Modifiers::CMD,
173 _ => {}
174 }
175 }
176 result
177 }
178
179 fn mouse_move(&mut self, x: i32, y: i32) -> AgentResult {
181 if let Err(e) = self.ensure_mouse() {
182 return AgentResult::err(e.to_string());
183 }
184 match self.mouse.move_by(x, y) {
185 Ok(_) => AgentResult::ok(),
186 Err(e) => AgentResult::err(e.to_string()),
187 }
188 }
189
190 fn mouse_click(&mut self, button: Option<String>) -> AgentResult {
191 if let Err(e) = self.ensure_mouse() {
192 return AgentResult::err(e.to_string());
193 }
194 let btn = Self::parse_mouse_button(button);
195 match self.mouse.click(btn) {
196 Ok(_) => AgentResult::ok(),
197 Err(e) => AgentResult::err(e.to_string()),
198 }
199 }
200
201 fn mouse_double_click(&mut self, button: Option<String>) -> AgentResult {
202 if let Err(e) = self.ensure_mouse() {
203 return AgentResult::err(e.to_string());
204 }
205 let btn = Self::parse_mouse_button(button);
206 match self.mouse.double_click(btn) {
207 Ok(_) => AgentResult::ok(),
208 Err(e) => AgentResult::err(e.to_string()),
209 }
210 }
211
212 fn mouse_down(&mut self, button: Option<String>) -> AgentResult {
213 if let Err(e) = self.ensure_mouse() {
214 return AgentResult::err(e.to_string());
215 }
216 let btn = Self::parse_mouse_button(button);
217 match self.mouse.press(btn) {
218 Ok(_) => AgentResult::ok(),
219 Err(e) => AgentResult::err(e.to_string()),
220 }
221 }
222
223 fn mouse_up(&mut self, button: Option<String>) -> AgentResult {
224 if let Err(e) = self.ensure_mouse() {
225 return AgentResult::err(e.to_string());
226 }
227 let btn = Self::parse_mouse_button(button);
228 match self.mouse.release(btn) {
229 Ok(_) => AgentResult::ok(),
230 Err(e) => AgentResult::err(e.to_string()),
231 }
232 }
233
234 fn mouse_scroll(&mut self, delta: i8) -> AgentResult {
235 if let Err(e) = self.ensure_mouse() {
236 return AgentResult::err(e.to_string());
237 }
238 match self.mouse.scroll(delta) {
239 Ok(_) => AgentResult::ok(),
240 Err(e) => AgentResult::err(e.to_string()),
241 }
242 }
243
244 fn type_text(&mut self, text: &str) -> AgentResult {
246 if let Err(e) = self.ensure_keyboard() {
247 return AgentResult::err(e.to_string());
248 }
249 match self.keyboard.type_text(text) {
250 Ok(_) => AgentResult::ok(),
251 Err(e) => AgentResult::err(e.to_string()),
252 }
253 }
254
255 fn key_press(&mut self, key: &str) -> AgentResult {
256 if let Err(e) = self.ensure_keyboard() {
257 return AgentResult::err(e.to_string());
258 }
259 match Key::from_str(key) {
260 Ok(k) => match self.keyboard.tap(k) {
261 Ok(_) => AgentResult::ok(),
262 Err(e) => AgentResult::err(e.to_string()),
263 },
264 Err(e) => AgentResult::err(e.to_string()),
265 }
266 }
267
268 fn key_down(&mut self, key: &str) -> AgentResult {
269 if let Err(e) = self.ensure_keyboard() {
270 return AgentResult::err(e.to_string());
271 }
272 match Key::from_str(key) {
273 Ok(k) => match self.keyboard.press_key(k) {
274 Ok(_) => AgentResult::ok(),
275 Err(e) => AgentResult::err(e.to_string()),
276 },
277 Err(e) => AgentResult::err(e.to_string()),
278 }
279 }
280
281 fn key_up(&mut self, key: &str) -> AgentResult {
282 if let Err(e) = self.ensure_keyboard() {
283 return AgentResult::err(e.to_string());
284 }
285 match Key::from_str(key) {
286 Ok(k) => match self.keyboard.release_key(k) {
287 Ok(_) => AgentResult::ok(),
288 Err(e) => AgentResult::err(e.to_string()),
289 },
290 Err(e) => AgentResult::err(e.to_string()),
291 }
292 }
293
294 fn key_combo(&mut self, modifiers: &[String], key: &str) -> AgentResult {
295 if let Err(e) = self.ensure_keyboard() {
296 return AgentResult::err(e.to_string());
297 }
298 let mods = Self::parse_modifiers(modifiers);
299 match Key::from_str(key) {
300 Ok(k) => match self.keyboard.press_combo(mods, k) {
301 Ok(_) => AgentResult::ok(),
302 Err(e) => AgentResult::err(e.to_string()),
303 },
304 Err(e) => AgentResult::err(e.to_string()),
305 }
306 }
307
308 fn gamepad_press(&mut self, button: &str) -> AgentResult {
310 if let Err(e) = self.ensure_gamepad() {
311 return AgentResult::err(e.to_string());
312 }
313 match Self::parse_gamepad_button(button) {
314 Ok(btn) => match self.gamepad.press(btn) {
315 Ok(_) => AgentResult::ok(),
316 Err(e) => AgentResult::err(e.to_string()),
317 },
318 Err(e) => AgentResult::err(e.to_string()),
319 }
320 }
321
322 fn gamepad_release(&mut self, button: &str) -> AgentResult {
323 if let Err(e) = self.ensure_gamepad() {
324 return AgentResult::err(e.to_string());
325 }
326 match Self::parse_gamepad_button(button) {
327 Ok(btn) => match self.gamepad.release(btn) {
328 Ok(_) => AgentResult::ok(),
329 Err(e) => AgentResult::err(e.to_string()),
330 },
331 Err(e) => AgentResult::err(e.to_string()),
332 }
333 }
334
335 fn gamepad_left_stick(&mut self, x: u8, y: u8) -> AgentResult {
336 if let Err(e) = self.ensure_gamepad() {
337 return AgentResult::err(e.to_string());
338 }
339 match self.gamepad.set_left_stick(x, y) {
340 Ok(_) => AgentResult::ok(),
341 Err(e) => AgentResult::err(e.to_string()),
342 }
343 }
344
345 fn gamepad_right_stick(&mut self, x: u8, y: u8) -> AgentResult {
346 if let Err(e) = self.ensure_gamepad() {
347 return AgentResult::err(e.to_string());
348 }
349 match self.gamepad.set_right_stick(x, y) {
350 Ok(_) => AgentResult::ok(),
351 Err(e) => AgentResult::err(e.to_string()),
352 }
353 }
354
355 fn gamepad_triggers(&mut self, left: u8, right: u8) -> AgentResult {
356 if let Err(e) = self.ensure_gamepad() {
357 return AgentResult::err(e.to_string());
358 }
359 if let Err(e) = self.gamepad.set_left_trigger(left) {
360 return AgentResult::err(e.to_string());
361 }
362 match self.gamepad.set_right_trigger(right) {
363 Ok(_) => AgentResult::ok(),
364 Err(e) => AgentResult::err(e.to_string()),
365 }
366 }
367}
368
369impl Default for AgentHID {
370 fn default() -> Self {
371 Self::new()
372 }
373}
374
375impl Drop for AgentHID {
376 fn drop(&mut self) {
377 if self.mouse_created {
378 let _ = self.mouse.destroy();
379 }
380 if self.keyboard_created {
381 let _ = self.keyboard.destroy();
382 }
383 if self.gamepad_created {
384 let _ = self.gamepad.destroy();
385 }
386 }
387}