如何将TOML配置文件中的字符反序列化为交叉项::event::KeyCode



我有一个.toml配置文件,其中包含一些用字符表示的键绑定,我需要将该文件反序列化为一个结构,其中每个字段都是crossterm::event::KeyCode。我使用toml板条箱来解析字符串。我的想法是,也许有一种方法可以将字符串解析键反序列化为char,然后将它们映射到KeyCode

config.toml:

key_0 = 'x'

key_bindings.rs:

use crossterm::event::KeyCode;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
pub struct KeyBindings {
pub key_0: KeyCode,
}

如何将config.toml文件反序列化为KeyBindings结构?

据我所知,既没有一个板条箱来进行从字符串到交叉项键的解析,甚至没有一个规范化的格式。

您还必须处理Crossterm和您的应用程序的细节。这尤其取决于你想如何使用钥匙。例如,如果要参数化从事件到动作的映射,则可能需要稍微转换键,使其与Crossterm可能产生的结果相匹配。

你可以使用这样一个函数:

/// parse a string as a keyboard key definition.
///
/// About the case:
/// The char we receive as code from crossterm is usually lowercase
/// but uppercase when it was typed with shift (i.e. we receive
/// "g" for a lowercase, and "shift-G" for an uppercase)
pub fn parse_key(raw: &str) -> Result<KeyEvent, ConfError> {
fn bad_key(raw: &str) -> Result<KeyEvent, ConfError> {
Err(ConfError::InvalidKey {
raw: raw.to_owned(),
})
}
let tokens: Vec<&str> = raw.split('-').collect();
let last = tokens[tokens.len() - 1].to_ascii_lowercase();
let mut code = match last.as_ref() {
"esc" => Esc,
"enter" => Enter,
"left" => Left,
"right" => Right,
"up" => Up,
"down" => Down,
"home" => Home,
"end" => End,
"pageup" => PageUp,
"pagedown" => PageDown,
"backtab" => BackTab,
"backspace" => Backspace,
"del" => Delete,
"delete" => Delete,
"insert" => Insert,
"ins" => Insert,
"f1" => F(1),
"f2" => F(2),
"f3" => F(3),
"f4" => F(4),
"f5" => F(5),
"f6" => F(6),
"f7" => F(7),
"f8" => F(8),
"f9" => F(9),
"f10" => F(10),
"f11" => F(11),
"f12" => F(12),
"space" => Char(' '),
"tab" => Tab,
c if c.len() == 1 => Char(c.chars().next().unwrap()),
_ => {
return bad_key(raw);
}
};
let mut modifiers = KeyModifiers::empty();
if code == BackTab {
// Crossterm always sends the shift key with  backtab
modifiers.insert(KeyModifiers::SHIFT);
}
for token in tokens.iter().take(tokens.len() - 1) {
match token.to_ascii_lowercase().as_ref() {
"ctrl" => {
modifiers.insert(KeyModifiers::CONTROL);
}
"alt" => {
modifiers.insert(KeyModifiers::ALT);
}
"shift" => {
modifiers.insert(KeyModifiers::SHIFT);
if let Char(c) = code {
if c.is_ascii_lowercase() {
code = Char(c.to_ascii_uppercase());
}
}
}
_ => {
return bad_key(raw);
}
}
}
Ok(KeyEvent { code, modifiers })
}

来源:broot 中的keys.rs

最新更新