mouse_codes/parser/
mod.rs1use crate::{
4 error::MouseParseError,
5 types::{Button, MouseEvent, ScrollDirection},
6};
7
8pub fn parse_button_with_aliases(s: &str) -> Result<Button, MouseParseError> {
10 let s = s.to_lowercase();
11 match s.as_str() {
12 "left" | "lmb" => Ok(Button::Left),
13 "right" | "rmb" => Ok(Button::Right),
14 "middle" | "mmb" | "wheel" => Ok(Button::Middle),
15 "x1" | "back" => Ok(Button::X1),
16 "x2" | "forward" => Ok(Button::X2),
17 "extra3" => Ok(Button::Extra3),
18 "extra4" => Ok(Button::Extra4),
19 "extra5" => Ok(Button::Extra5),
20 "extra6" => Ok(Button::Extra6),
21 "extra7" => Ok(Button::Extra7),
22 "extra8" => Ok(Button::Extra8),
23 #[cfg(feature = "extended")]
24 "extra9" => Ok(Button::Extra9),
25 #[cfg(feature = "extended")]
26 "extra10" => Ok(Button::Extra10),
27 _ => Err(MouseParseError::UnknownButton(s)),
28 }
29}
30
31pub fn parse_scroll_direction(s: &str) -> Result<ScrollDirection, MouseParseError> {
33 let s = s.to_lowercase();
34 match s.as_str() {
35 "verticalup" | "up" => Ok(ScrollDirection::VerticalUp),
36 "verticaldown" | "down" => Ok(ScrollDirection::VerticalDown),
37 "horizontalleft" | "left" => Ok(ScrollDirection::HorizontalLeft),
38 "horizontalright" | "right" => Ok(ScrollDirection::HorizontalRight),
39 _ => Err(MouseParseError::UnknownButton(s)),
40 }
41}
42
43pub fn parse_mouse_input(s: &str) -> Result<MouseEvent, MouseParseError> {
45 if s.is_empty() {
46 return Err(MouseParseError::EmptyInput);
47 }
48
49 let (event_type, params) = s
50 .split_once('(')
51 .and_then(|(t, p)| p.strip_suffix(')').map(|p| (t, p)))
52 .ok_or_else(|| MouseParseError::UnknownButton(s.to_string()))?;
53
54 match event_type {
55 "Press" => {
56 let button = parse_button_with_aliases(params)?;
57 Ok(MouseEvent::Press(button))
58 }
59 "Release" => {
60 let button = parse_button_with_aliases(params)?;
61 Ok(MouseEvent::Release(button))
62 }
63 "Scroll" => {
64 let parts: Vec<&str> = params.split(',').map(|s| s.trim()).collect();
65 if parts.len() != 2 {
66 return Err(MouseParseError::UnknownButton(s.to_string()));
67 }
68 let dir = parse_scroll_direction(parts[0])?;
69 let amount = parts[1]
70 .parse()
71 .map_err(|_| MouseParseError::UnknownButton(s.to_string()))?;
72 Ok(MouseEvent::Scroll(dir, amount))
73 }
74 "Move" => {
75 let parts: Vec<&str> = params.split(',').map(|s| s.trim()).collect();
76 if parts.len() != 2 {
77 return Err(MouseParseError::UnknownButton(s.to_string()));
78 }
79 let x = parts[0]
80 .parse()
81 .map_err(|_| MouseParseError::UnknownButton(s.to_string()))?;
82 let y = parts[1]
83 .parse()
84 .map_err(|_| MouseParseError::UnknownButton(s.to_string()))?;
85 Ok(MouseEvent::Move(x, y))
86 }
87 "RelativeMove" => {
88 let parts: Vec<&str> = params.split(',').map(|s| s.trim()).collect();
89 if parts.len() != 2 {
90 return Err(MouseParseError::UnknownButton(s.to_string()));
91 }
92 let dx = parts[0]
93 .parse()
94 .map_err(|_| MouseParseError::UnknownButton(s.to_string()))?;
95 let dy = parts[1]
96 .parse()
97 .map_err(|_| MouseParseError::UnknownButton(s.to_string()))?;
98 Ok(MouseEvent::RelativeMove(dx, dy))
99 }
100 _ => Err(MouseParseError::UnknownButton(s.to_string())),
101 }
102}