Break up config source files

pull/39/head
Takashi Kokubun 3 years ago
parent 16615e55d3
commit fed0b5526f
No known key found for this signature in database
GPG Key ID: 6FFC433B12EE23DD

@ -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 });
}

@ -1,12 +1,15 @@
mod key;
mod keymap;
mod keypress;
mod modmap;
mod wm_class;
extern crate serde_yaml;
use evdev::Key;
use serde::de::{value, Error, MapAccess, SeqAccess, Visitor};
use serde::{de, Deserialize, Deserializer};
use std::collections::HashMap;
use std::{error, fmt, fs};
use keymap::Keymap;
use modmap::Modmap;
use serde::Deserialize;
use std::{error, fs};
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
@ -15,97 +18,8 @@ pub struct Config {
pub keymap: Vec<Keymap>,
}
#[derive(Debug, Deserialize)]
pub struct Modmap {
pub name: String,
#[serde(deserialize_with = "modmap_remap")]
pub remap: HashMap<Key, Key>,
pub wm_class: Option<WMClass>,
}
#[derive(Debug, Deserialize)]
pub struct Keymap {
pub name: String,
pub remap: HashMap<String, String>,
pub wm_class: Option<WMClass>,
}
// TODO: Use trait to allow only either `only` or `not`
#[derive(Debug, Deserialize)]
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>>,
}
pub fn load_config(filename: &str) -> Result<Config, Box<dyn error::Error>> {
let yaml = fs::read_to_string(&filename)?;
let config: Config = serde_yaml::from_str(&yaml)?;
return Ok(config);
}
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 of 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 key_remap = HashMap::new();
for (from, to) in remap.iter() {
let from_key = key::parse_key(&from).map_err(M::Error::custom)?;
let to_key = key::parse_key(&to).map_err(M::Error::custom)?;
key_remap.insert(from_key, to_key);
}
Ok(key_remap)
}
}
deserializer.deserialize_any(ModmapRemap)
}
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)
}

@ -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…
Cancel
Save