Simplify KeyAction deserializer

pull/53/head
Takashi Kokubun 2 years ago
parent 4280a3f559
commit 179674e713
No known key found for this signature in database
GPG Key ID: 6FFC433B12EE23DD

@ -71,7 +71,7 @@ impl<'de> Deserialize<'de> for Action {
}
}
pub fn serde_error<'de, V, M>(message: &str) -> Result<V, M::Error>
fn serde_error<'de, V, M>(message: &str) -> Result<V, M::Error>
where
M: MapAccess<'de>,
{

@ -1,7 +1,34 @@
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();

@ -1,102 +1,26 @@
use crate::config::action::serde_error;
use crate::config::key::parse_key;
use crate::config::key::deserialize_key;
use evdev::Key;
use serde::de::{MapAccess, Visitor};
use serde::{Deserialize, Deserializer};
use std::fmt::Formatter;
use std::time::Duration;
static DEFAULT_ALONE_TIMEOUT_MILLIS: u64 = 1000;
use serde::Deserialize;
// Values in `modmap.remap`
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize)]
#[serde(untagged)]
pub enum KeyAction {
#[serde(deserialize_with = "deserialize_key")]
Key(Key),
MultiPurposeKey(MultiPurposeKey),
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize)]
pub struct MultiPurposeKey {
#[serde(deserialize_with = "deserialize_key")]
pub held: Key,
#[serde(deserialize_with = "deserialize_key")]
pub alone: Key,
pub alone_timeout: Duration,
#[serde(default = "default_alone_timeout_millis")]
pub alone_timeout_millis: u64,
}
impl<'de> Deserialize<'de> for KeyAction {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct KeyActionVisitor;
impl<'de> Visitor<'de> for KeyActionVisitor {
type Value = KeyAction;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("string or map")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let key = parse_key(value).map_err(serde::de::Error::custom)?;
Ok(KeyAction::Key(key))
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut held: Option<Key> = None;
let mut alone: Option<Key> = None;
let mut alone_timeout_millis: u64 = DEFAULT_ALONE_TIMEOUT_MILLIS;
while let Some(key) = map.next_key::<String>()? {
match &key[..] {
"held" => {
let value: String = map.next_value()?;
held = Some(parse_key(&value).map_err(serde::de::Error::custom)?)
}
"alone" => {
let value: String = map.next_value()?;
alone = Some(parse_key(&value).map_err(serde::de::Error::custom)?)
}
"alone_timeout_millis" => alone_timeout_millis = map.next_value()?,
key => {
return serde_error::<Self::Value, M>(&format!(
"held, alone, or alone_timeout_ms is expected, but got: {}",
key
))
}
}
}
let held = match held {
Some(held) => held,
None => {
return serde_error::<Self::Value, M>(
"held is not specified in a multi-purpose remap of modmap",
)
}
};
let alone = match alone {
Some(alone) => alone,
None => {
return serde_error::<Self::Value, M>(
"alone is not specified in a multi-purpose remap of modmap",
)
}
};
let multi_purpose_key = MultiPurposeKey {
held,
alone,
alone_timeout: Duration::from_millis(alone_timeout_millis),
};
Ok(KeyAction::MultiPurposeKey(multi_purpose_key))
}
}
deserializer.deserialize_any(KeyActionVisitor)
}
fn default_alone_timeout_millis() -> u64 {
1000
}

@ -10,7 +10,7 @@ use lazy_static::lazy_static;
use log::debug;
use std::collections::HashMap;
use std::error::Error;
use std::time::Instant;
use std::time::{Duration, Instant};
pub struct EventHandler {
device: VirtualDevice,
@ -92,7 +92,9 @@ impl EventHandler {
MultiPurposeKeyState {
held: multi_purpose_key.held,
alone: multi_purpose_key.alone,
alone_timeout_at: Some(Instant::now() + multi_purpose_key.alone_timeout),
alone_timeout_at: Some(
Instant::now() + Duration::from_millis(multi_purpose_key.alone_timeout_millis),
),
},
);
return vec![]; // delay the press

Loading…
Cancel
Save