You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xremap/src/config/key.rs

73 lines
1.9 KiB
Rust

use evdev::Key;
use serde::de::Visitor;
use serde::Deserializer;
use std::error::Error;
use std::fmt;
use std::str::FromStr;
pub fn deserialize_key<'de, D>(deserializer: D) -> Result<evdev::Key, D::Error>
where
D: Deserializer<'de>,
{
struct KeyVisitor;
impl<'de> Visitor<'de> for KeyVisitor {
type Value = evdev::Key;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("string")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(parse_key(value).map_err(serde::de::Error::custom)?)
}
}
deserializer.deserialize_any(KeyVisitor)
}
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[..] {
2 years ago
// Shift
"SHIFT_R" => Key::KEY_RIGHTSHIFT,
"SHIFT_L" => Key::KEY_LEFTSHIFT,
2 years ago
// Control
"CONTROL_R" => Key::KEY_RIGHTCTRL,
"CONTROL_L" => Key::KEY_LEFTCTRL,
"CTRL_R" => Key::KEY_RIGHTCTRL,
"CTRL_L" => Key::KEY_LEFTCTRL,
2 years ago
// Alt
"ALT_R" => Key::KEY_RIGHTALT,
"ALT_L" => Key::KEY_LEFTALT,
2 years ago
// Windows
"SUPER_R" => Key::KEY_RIGHTMETA,
"SUPER_L" => Key::KEY_LEFTMETA,
"WIN_R" => Key::KEY_RIGHTMETA,
"WIN_L" => Key::KEY_LEFTMETA,
2 years ago
// else
_ => Key::KEY_RESERVED,
};
if key != Key::KEY_RESERVED {
return Ok(key);
}
return Err(format!("unknown key '{}'", input).into());
}