forked from xremap/xremap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
key.rs
58 lines (52 loc) · 1.66 KB
/
key.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use evdev::Key;
use serde::{Deserialize, Deserializer};
use std::error::Error;
use std::str::FromStr;
pub fn deserialize_key<'de, D>(deserializer: D) -> Result<Key, D::Error>
where
D: Deserializer<'de>,
{
let key = String::deserialize(deserializer)?;
parse_key(&key).map_err(serde::de::Error::custom)
}
pub fn parse_key(input: &str) -> Result<Key, Box<dyn Error>> {
// Everything is case-insensitive
let name = input.to_uppercase();
// Original evdev scancodes should always work
if let Ok(key) = Key::from_str(&name) {
return Ok(key);
}
// You can abbreviate "KEY_" of any "KEY_*" scancodes.
if let Ok(key) = Key::from_str(&format!("KEY_{}", name)) {
return Ok(key);
}
// xremap's custom aliases like k0kubun/karabiner-dsl
let key = match &name[..] {
// Shift
"SHIFT_R" => Key::KEY_RIGHTSHIFT,
"SHIFT_L" => Key::KEY_LEFTSHIFT,
// Control
"CONTROL_R" => Key::KEY_RIGHTCTRL,
"CONTROL_L" => Key::KEY_LEFTCTRL,
"CTRL_R" => Key::KEY_RIGHTCTRL,
"CTRL_L" => Key::KEY_LEFTCTRL,
"C_R" => Key::KEY_RIGHTCTRL,
"C_L" => Key::KEY_LEFTCTRL,
// Alt
"ALT_R" => Key::KEY_RIGHTALT,
"ALT_L" => Key::KEY_LEFTALT,
"M_R" => Key::KEY_RIGHTALT,
"M_L" => Key::KEY_LEFTALT,
// Windows
"SUPER_R" => Key::KEY_RIGHTMETA,
"SUPER_L" => Key::KEY_LEFTMETA,
"WIN_R" => Key::KEY_RIGHTMETA,
"WIN_L" => Key::KEY_LEFTMETA,
// else
_ => Key::KEY_RESERVED,
};
if key != Key::KEY_RESERVED {
return Ok(key);
}
return Err(format!("unknown key '{}'", input).into());
}