1use core::{fmt, str::FromStr};
15use num_derive::{FromPrimitive, ToPrimitive};
16use num_traits::FromPrimitive;
17
18#[derive(
19 Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, FromPrimitive, ToPrimitive,
20)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22pub enum MouseCode {
23 #[default]
24 None = 0xff,
25 Mouse1 = 0x0,
26 Mouse2 = 0x1,
28 Mouse3 = 0x2,
30 Mouse4 = 0x3,
32 Mouse5 = 0x4,
34 Mouse6 = 0x5,
36 Mouse7 = 0x6,
37 Mouse8 = 0x7,
38 MouseWheelUp = 0x8,
39 MouseWheelDown = 0x9,
40 MouseMove = 0xa,
41
42 LeftMouseButton = 256,
45 RightMouseButton = 257,
46 MiddleWheelMouseButton = 258,
47 MouseButton3 = 259,
48 MouseButton4 = 260,
49 MouseButton5 = 261,
50 MouseButton6 = 262,
51 MouseButton7 = 263,
52 MouseWheelUp_ = 264,
53 MouseWheelDown_ = 265,
54}
55
56#[allow(non_camel_case_types)]
57#[derive(
58 Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, FromPrimitive, ToPrimitive,
59)]
60#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
61pub enum GamepadCode {
62 #[default]
63 None = 0xff,
64 Up = 0x0001,
65 Down = 0x0002,
66 Left = 0x0004,
67 Right = 0x008,
68 _360_Start = 0x0010,
69 _360_Back = 0x0020,
70 _360_L3 = 0x0040,
71 _360_R3 = 0x0080,
72 _360_LB = 0x0100,
73 _360_RB = 0x0200,
74 _360_A = 0x1000,
75 _360_B = 0x2000,
76 _360_X = 0x4000,
77 _360_Y = 0x8000,
78 _360_LT = 0x0009,
79 _360_RT = 0x000a,
80 _360_LS = 0x000b,
81 _360_RS = 0x000c,
82
83 DpadUp = 266,
86 DpadDown = 267,
87 DpadLeft = 268,
88 DpadRight = 269,
89 Start = 270,
90 Back = 271,
91 LeftThumb = 272,
92 RightThumb = 273,
93 LeftShoulder = 274,
94 RightShoulder = 275,
95 AButton = 276,
96 BButton = 277,
97 XButton = 278,
98 YButton = 279,
99 LeftTrigger = 280,
100 RightTrigger = 281,
101}
102
103#[allow(non_camel_case_types)]
106#[derive(
107 Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, FromPrimitive, ToPrimitive,
108)]
109#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
110pub enum KeyboardCode {
111 #[default]
112 None = 0xff,
113 Esc = 0x01,
114 _1 = 0x02,
115 _2 = 0x03,
116 _3 = 0x04,
117 _4 = 0x05,
118 _5 = 0x06,
119 _6 = 0x07,
120 _7 = 0x08,
121 _8 = 0x09,
122 _9 = 0x0a,
123 _0 = 0x0b,
124 Hyphen = 0x0c,
125 Equal = 0x0d,
126 Backspace = 0x0e,
127 Tab = 0x0f,
128 Q = 0x10,
129 W = 0x11,
130 E = 0x12,
131 R = 0x13,
132 T = 0x14,
133 Y = 0x15,
134 U = 0x16,
135 I = 0x17,
136 O = 0x18,
137 P = 0x19,
138 Bracketleft = 0x1a,
139 Bracketright = 0x1b,
140 Enter = 0x1c,
141 LCtrl = 0x1d,
142 A = 0x1e,
143 S = 0x1f,
144 D = 0x20,
145 F = 0x21,
146 G = 0x22,
147 H = 0x23,
148 J = 0x24,
149 K = 0x25,
150 L = 0x26,
151 Semicolon = 0x27,
152 Quotesingle = 0x28,
153 Tilde = 0x29,
154 LShift = 0x2a,
155 Backslash = 0x2b,
156 Z = 0x2c,
157 X = 0x2d,
158 C = 0x2e,
159 V = 0x2f,
160 B = 0x30,
161 N = 0x31,
162 M = 0x32,
163 Comma = 0x33,
164 Period = 0x34,
165 Slash = 0x35,
166 RShift = 0x36,
167 NumpadMult = 0x37,
168 LAlt = 0x38,
169 Space = 0x39,
170 CapsLock = 0x3a,
171 F1 = 0x3b,
172 F2 = 0x3c,
173 F3 = 0x3d,
174 F4 = 0x3e,
175 F5 = 0x3f,
176 F6 = 0x40,
177 F7 = 0x41,
178 F8 = 0x42,
179 F9 = 0x43,
180 F10 = 0x44,
181 NumLock = 0x45,
182 ScrollLock = 0x46,
183 Numpad7 = 0x47,
184 Numpad8 = 0x48,
185 Numpad9 = 0x49,
186 NumpadMinus = 0x4a,
187 Numpad4 = 0x4b,
188 Numpad5 = 0x4c,
189 Numpad6 = 0x4d,
190 NumpadPlus = 0x4e,
191 Numpad1 = 0x4f,
192 Numpad2 = 0x50,
193 Numpad3 = 0x51,
194 Numpad0 = 0x52,
195 NumpadDec = 0x53,
196 DIK_OEM_102 = 0x56,
197 F11 = 0x57,
198 F12 = 0x58,
199 F13 = 0x64,
200 F14 = 0x65,
201 F15 = 0x66,
202 DIK_KANA = 0x70,
203 DIK_ABNT_C1 = 0x73,
204 DIK_CONVERT = 0x79,
205 DIK_NOCONVERT = 0x7b,
206 Unknown = 0x7d,
207 DIK_ABNT_C2 = 0x7e,
208 NumPadEqual = 0x8d,
209 PrevTrack = 0x90,
210 DIK_AT = 0x91,
211 Colon = 0x92,
212 DIK_UNDERLINE = 0x93,
213 DIK_KANJI = 0x94,
214 DIK_STOP = 0x95,
215 DIK_AX = 0x96,
216 DIK_UNLABELED = 0x97,
217 NextTrack = 0x99,
218 NumPadEnter = 0x9c,
219 RCtrl = 0x9d,
220 Mute = 0xa0,
221 Calc = 0xa1,
222 PlayPause = 0xa2,
223 MediaStop = 0xa4,
224 VolMinus = 0xae,
225 VolPlus = 0xb0,
226 WebHome = 0xb2,
227 NumpadComma = 0xb3,
228 NumpadDivide = 0xb5,
229 PrintSrc = 0xb7,
230 RAlt = 0xb8,
231 Pause = 0xc5,
232 Home = 0xc7,
233 UpArrow = 0xc8,
234 PgUp = 0xc9,
235 Left = 0xcb,
236 Right = 0xcd,
237 End = 0xcf,
238 DownArrow = 0xd0,
239 PgDn = 0xd1,
240 Insert = 0xd2,
241 Delete = 0xd3,
242 LWindows = 0xdb,
243 RWindows = 0xdc,
244 Apps = 0xdd,
245 Power = 0xde,
246 Sleep = 0xdf,
247 Wake = 0xe3,
248 WebSearch = 0xe5,
249 WebFavorites = 0xe6,
250 WebRefresh = 0xe7,
251 WebStop = 0xe8,
252 WebForward = 0xe9,
253 WebBack = 0xea,
254 MyComputer = 0xeb,
255 Mail = 0xec,
256 MediaSelect = 0xed,
257}
258
259trait ToRaw {
262 fn to_raw(&self) -> usize;
264}
265
266macro_rules! impl_cast {
267 ($($self:ident),+ $(,)?) => {
268 $(
269 impl ToRaw for $self {
270 fn to_raw(&self) -> usize {
271 self.clone() as usize
272 }
273 }
274 impl TryFrom<usize> for $self {
275 type Error = ScanCodeError;
276
277 fn try_from(value: usize) -> Result<Self, Self::Error> {
278 FromPrimitive::from_usize(value)
279 .ok_or_else(|| ScanCodeError::InvalidDigit(format!("{}", value)))
280 }
281 }
282 impl FromStr for $self {
283 type Err = ScanCodeError;
284
285 fn from_str(s: &str) -> Result<Self, Self::Err> {
286 let radix = match s.chars().next() {
287 Some('0') => {
288 match s.chars().nth(1) {
289 Some('x') | Some('X') => 16, Some('o') | Some('O') => 8, Some('b') | Some('B') => 2, _ => 10, }
294 }
295 _ => 10, };
297
298 let s = if radix != 10 { &s[2..] } else { s };
299 Self::try_from(
300 usize::from_str_radix(s, radix)
301 .map_err(|_| ScanCodeError::InvalidDigit(s.into()))?,
302 )
303 }
304 }
305 impl fmt::Display for $self {
306 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
307 write!(f, "0x{:x}", self.to_raw())
308 }
309 }
310 )+
311 };
312}
313
314impl_cast!(GamepadCode, KeyboardCode, MouseCode);
315
316#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
317#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
318pub enum ScanCodeError {
319 #[error("invalid digit found in string. got {0}")]
320 InvalidDigit(String),
321}