mirror of https://github.com/k0kubun/xremap
Break up config source files
parent
16615e55d3
commit
fed0b5526f
@ -0,0 +1,51 @@
|
||||
use crate::config::keypress::{parse_keypress, KeyPress};
|
||||
use crate::config::wm_class::WMClass;
|
||||
use serde::de::{value, Error, MapAccess, Visitor};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Keymap {
|
||||
pub name: String,
|
||||
#[serde(deserialize_with = "keymap_remap")]
|
||||
pub remap: HashMap<KeyPress, Vec<KeyPress>>,
|
||||
pub wm_class: Option<WMClass>,
|
||||
}
|
||||
|
||||
// TODO: Add Action trait
|
||||
|
||||
fn keymap_remap<'de, D>(deserializer: D) -> Result<HashMap<KeyPress, Vec<KeyPress>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct KeymapRemap;
|
||||
|
||||
impl<'de> Visitor<'de> for KeymapRemap {
|
||||
type Value = HashMap<KeyPress, Vec<KeyPress>>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("map from string to string, array, or map")
|
||||
}
|
||||
|
||||
fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
|
||||
where
|
||||
M: MapAccess<'de>,
|
||||
{
|
||||
let remap: HashMap<String, String> =
|
||||
Deserialize::deserialize(value::MapAccessDeserializer::new(map))?;
|
||||
let mut keymap = HashMap::new();
|
||||
|
||||
for (from, to) in remap.iter() {
|
||||
let from_keymap = parse_keypress(&from).map_err(M::Error::custom)?;
|
||||
let to_keymap = parse_keypress(&to).map_err(M::Error::custom)?;
|
||||
keymap.insert(from_keymap, vec![to_keymap]);
|
||||
}
|
||||
|
||||
Ok(keymap)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_any(KeymapRemap)
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
use crate::config::key::parse_key;
|
||||
use evdev::Key;
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||
pub struct KeyPress {
|
||||
pub key: Key,
|
||||
}
|
||||
|
||||
pub fn parse_keypress(input: &str) -> Result<KeyPress, Box<dyn Error>> {
|
||||
let key = parse_key(input)?;
|
||||
return Ok(KeyPress { key });
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
use crate::config::key::parse_key;
|
||||
use crate::config::wm_class::WMClass;
|
||||
use evdev::Key;
|
||||
use serde::de::{value, Error, MapAccess, Visitor};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Modmap {
|
||||
pub name: String,
|
||||
#[serde(deserialize_with = "modmap_remap")]
|
||||
pub remap: HashMap<Key, Key>,
|
||||
pub wm_class: Option<WMClass>,
|
||||
}
|
||||
|
||||
fn modmap_remap<'de, D>(deserializer: D) -> Result<HashMap<Key, Key>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct ModmapRemap;
|
||||
|
||||
impl<'de> Visitor<'de> for ModmapRemap {
|
||||
type Value = HashMap<Key, Key>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("map from string to string")
|
||||
}
|
||||
|
||||
fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
|
||||
where
|
||||
M: MapAccess<'de>,
|
||||
{
|
||||
let remap: HashMap<String, String> =
|
||||
Deserialize::deserialize(value::MapAccessDeserializer::new(map))?;
|
||||
let mut modmap = HashMap::new();
|
||||
|
||||
for (from, to) in remap.iter() {
|
||||
let from_key = parse_key(&from).map_err(M::Error::custom)?;
|
||||
let to_key = parse_key(&to).map_err(M::Error::custom)?;
|
||||
modmap.insert(from_key, to_key);
|
||||
}
|
||||
|
||||
Ok(modmap)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_any(ModmapRemap)
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
use serde::de::{value, SeqAccess, Visitor};
|
||||
use serde::{de, Deserialize, Deserializer};
|
||||
use std::fmt;
|
||||
|
||||
// TODO: Use trait to allow only either `only` or `not`
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct WMClass {
|
||||
#[serde(default, deserialize_with = "string_or_vec")]
|
||||
pub only: Option<Vec<String>>,
|
||||
#[serde(default, deserialize_with = "string_or_vec")]
|
||||
pub not: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
fn string_or_vec<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct StringOrVec;
|
||||
|
||||
impl<'de> Visitor<'de> for StringOrVec {
|
||||
type Value = Option<Vec<String>>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("string or list of strings")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
Ok(Some(vec![s.to_owned()]))
|
||||
}
|
||||
|
||||
fn visit_seq<S>(self, seq: S) -> Result<Self::Value, S::Error>
|
||||
where
|
||||
S: SeqAccess<'de>,
|
||||
{
|
||||
let result: Vec<String> =
|
||||
Deserialize::deserialize(value::SeqAccessDeserializer::new(seq))?;
|
||||
Ok(Some(result))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_any(StringOrVec)
|
||||
}
|
Loading…
Reference in New Issue