mouse_codes/mapping/standard/
hashmap_impl.rs

1//! Standard mapping implementation using std::collections::HashMap
2
3use crate::types::{Button, Platform};
4use std::collections::HashMap;
5use std::sync::LazyLock;
6
7static WINDOWS_CODE_MAP: LazyLock<HashMap<Button, usize>> = LazyLock::new(|| {
8    HashMap::from([
9        (Button::Left, 1),
10        (Button::Right, 2),
11        (Button::Middle, 4),
12        (Button::X1, 5),
13        (Button::X2, 6),
14        (Button::Extra3, 7),
15        (Button::Extra4, 8),
16        (Button::Extra5, 9),
17        (Button::Extra6, 10),
18        (Button::Extra7, 11),
19        (Button::Extra8, 12),
20        #[cfg(feature = "extended")]
21        (Button::Extra9, 13),
22        #[cfg(feature = "extended")]
23        (Button::Extra10, 14),
24    ])
25});
26
27static LINUX_CODE_MAP: LazyLock<HashMap<Button, usize>> = LazyLock::new(|| {
28    HashMap::from([
29        (Button::Left, 1),
30        (Button::Right, 3),
31        (Button::Middle, 2),
32        (Button::X1, 8),
33        (Button::X2, 9),
34        (Button::Extra3, 10),
35        (Button::Extra4, 11),
36        (Button::Extra5, 12),
37        (Button::Extra6, 13),
38        (Button::Extra7, 14),
39        (Button::Extra8, 15),
40        #[cfg(feature = "extended")]
41        (Button::Extra9, 16),
42        #[cfg(feature = "extended")]
43        (Button::Extra10, 17),
44    ])
45});
46
47static MACOS_CODE_MAP: LazyLock<HashMap<Button, usize>> = LazyLock::new(|| {
48    HashMap::from([
49        (Button::Left, 0),
50        (Button::Right, 1),
51        (Button::Middle, 2),
52        (Button::X1, 3),
53        (Button::X2, 4),
54        (Button::Extra3, 5),
55        (Button::Extra4, 6),
56        (Button::Extra5, 7),
57        (Button::Extra6, 8),
58        (Button::Extra7, 9),
59        (Button::Extra8, 10),
60        #[cfg(feature = "extended")]
61        (Button::Extra9, 11),
62        #[cfg(feature = "extended")]
63        (Button::Extra10, 12),
64    ])
65});
66
67static WINDOWS_REVERSE_MAP: LazyLock<HashMap<usize, Button>> = LazyLock::new(|| {
68    HashMap::from([
69        (1, Button::Left),
70        (2, Button::Right),
71        (4, Button::Middle),
72        (5, Button::X1),
73        (6, Button::X2),
74        (7, Button::Extra3),
75        (8, Button::Extra4),
76        (9, Button::Extra5),
77        (10, Button::Extra6),
78        (11, Button::Extra7),
79        (12, Button::Extra8),
80        #[cfg(feature = "extended")]
81        (13, Button::Extra9),
82        #[cfg(feature = "extended")]
83        (14, Button::Extra10),
84    ])
85});
86
87static LINUX_REVERSE_MAP: LazyLock<HashMap<usize, Button>> = LazyLock::new(|| {
88    HashMap::from([
89        (1, Button::Left),
90        (3, Button::Right),
91        (2, Button::Middle),
92        (8, Button::X1),
93        (9, Button::X2),
94        (10, Button::Extra3),
95        (11, Button::Extra4),
96        (12, Button::Extra5),
97        (13, Button::Extra6),
98        (14, Button::Extra7),
99        (15, Button::Extra8),
100        #[cfg(feature = "extended")]
101        (16, Button::Extra9),
102        #[cfg(feature = "extended")]
103        (17, Button::Extra10),
104    ])
105});
106
107static MACOS_REVERSE_MAP: LazyLock<HashMap<usize, Button>> = LazyLock::new(|| {
108    HashMap::from([
109        (0, Button::Left),
110        (1, Button::Right),
111        (2, Button::Middle),
112        (3, Button::X1),
113        (4, Button::X2),
114        (5, Button::Extra3),
115        (6, Button::Extra4),
116        (7, Button::Extra5),
117        (8, Button::Extra6),
118        (9, Button::Extra7),
119        (10, Button::Extra8),
120        #[cfg(feature = "extended")]
121        (11, Button::Extra9),
122        #[cfg(feature = "extended")]
123        (12, Button::Extra10),
124    ])
125});
126
127/// HashMap implementation of the CodeMapper trait
128pub trait CodeMapperImpl {
129    /// Convert the button to a platform-specific code
130    fn to_code(&self, platform: Platform) -> usize;
131
132    /// Parse a button from a platform-specific code
133    fn from_code(code: usize, platform: Platform) -> Option<Self>
134    where
135        Self: Sized;
136}
137
138impl CodeMapperImpl for Button {
139    fn to_code(&self, platform: Platform) -> usize {
140        match platform {
141            Platform::Windows => *WINDOWS_CODE_MAP
142                .get(self)
143                .expect("Invalid button for Windows platform"),
144            Platform::Linux => *LINUX_CODE_MAP
145                .get(self)
146                .expect("Invalid button for Linux platform"),
147            Platform::MacOS => *MACOS_CODE_MAP
148                .get(self)
149                .expect("Invalid button for macOS platform"),
150        }
151    }
152
153    fn from_code(code: usize, platform: Platform) -> Option<Self> {
154        match platform {
155            Platform::Windows => WINDOWS_REVERSE_MAP.get(&code).copied(),
156            Platform::Linux => LINUX_REVERSE_MAP.get(&code).copied(),
157            Platform::MacOS => MACOS_REVERSE_MAP.get(&code).copied(),
158        }
159    }
160}