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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
use anyhow::Context;
pub use evdev_rs::enums::{EventCode, EventType, EV_KEY as KeyCode};
use serde::Deserialize;
use std::collections::HashSet;
use std::path::Path;
use thiserror::Error;
#[derive(Debug, Clone)]
pub struct MappingConfig {
pub device_name: String,
pub mappings: Vec<Mapping>,
}
impl MappingConfig {
pub fn from_file<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
let path = path.as_ref();
let toml_data = std::fs::read_to_string(path)
.context(format!("reading toml from {}", path.display()))?;
let config_file: ConfigFile =
toml::from_str(&toml_data).context(format!("parsing toml from {}", path.display()))?;
let mut mappings = vec![];
for dual in config_file.dual_role {
mappings.push(dual.into());
}
for remap in config_file.remap {
mappings.push(remap.into());
}
Ok(Self {
device_name: config_file.device_name,
mappings,
})
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Mapping {
DualRole {
input: KeyCode,
hold: Vec<KeyCode>,
tap: Vec<KeyCode>,
},
Remap {
input: HashSet<KeyCode>,
output: HashSet<KeyCode>,
},
}
#[derive(Debug, Deserialize)]
#[serde(try_from = "String")]
struct KeyCodeWrapper {
pub code: KeyCode,
}
impl Into<KeyCode> for KeyCodeWrapper {
fn into(self) -> KeyCode {
self.code
}
}
#[derive(Error, Debug)]
pub enum ConfigError {
#[error("Invalid key `{0}`. Use `evremap list-keys` to see possible keys.")]
InvalidKey(String),
#[error("Impossible: parsed KEY_XXX but not into an EV_KEY")]
ImpossibleParseKey,
}
impl std::convert::TryFrom<String> for KeyCodeWrapper {
type Error = ConfigError;
fn try_from(s: String) -> Result<KeyCodeWrapper, Self::Error> {
match EventCode::from_str(&EventType::EV_KEY, &s) {
Some(code) => match code {
EventCode::EV_KEY(code) => Ok(KeyCodeWrapper { code }),
_ => Err(ConfigError::ImpossibleParseKey),
},
None => Err(ConfigError::InvalidKey(s)),
}
}
}
#[derive(Debug, Deserialize)]
struct DualRoleConfig {
input: KeyCodeWrapper,
hold: Vec<KeyCodeWrapper>,
tap: Vec<KeyCodeWrapper>,
}
impl Into<Mapping> for DualRoleConfig {
fn into(self) -> Mapping {
Mapping::DualRole {
input: self.input.into(),
hold: self.hold.into_iter().map(Into::into).collect(),
tap: self.tap.into_iter().map(Into::into).collect(),
}
}
}
#[derive(Debug, Deserialize)]
struct RemapConfig {
input: Vec<KeyCodeWrapper>,
output: Vec<KeyCodeWrapper>,
}
impl Into<Mapping> for RemapConfig {
fn into(self) -> Mapping {
Mapping::Remap {
input: self.input.into_iter().map(Into::into).collect(),
output: self.output.into_iter().map(Into::into).collect(),
}
}
}
#[derive(Debug, Deserialize)]
struct ConfigFile {
device_name: String,
#[serde(default)]
dual_role: Vec<DualRoleConfig>,
#[serde(default)]
remap: Vec<RemapConfig>,
}
|