Deserialize and eval Action
This commit is contained in:
parent
1e00746636
commit
296c807c72
|
@ -15,6 +15,7 @@
|
|||
|
||||
#![allow(dead_code, clippy::module_name_repetitions)]
|
||||
|
||||
use crate::msg_listener::Action;
|
||||
use crate::Result;
|
||||
use breadx::auto::xproto::KeyButMask;
|
||||
use serde::{
|
||||
|
@ -32,8 +33,9 @@ pub struct XcrabConfig {
|
|||
gap_size: Option<u16>,
|
||||
outer_gap_size: Option<u16>,
|
||||
pub msg: Option<XcrabMsgConfig>,
|
||||
#[allow(clippy::zero_sized_map_values)] // TODO: Action will be expanded in the future
|
||||
#[serde(default)]
|
||||
pub binds: HashMap<Keybind, String>,
|
||||
pub binds: HashMap<Keybind, Action>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
|
@ -105,6 +107,25 @@ fn get_home() -> Result<String> {
|
|||
Ok(std::env::var("HOME")?)
|
||||
}
|
||||
|
||||
struct ActionVisitor;
|
||||
impl<'de> Visitor<'de> for ActionVisitor {
|
||||
type Value = Action;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a valid WM action")
|
||||
}
|
||||
|
||||
fn visit_str<E: serde::de::Error>(self, value: &str) -> std::result::Result<Self::Value, E> {
|
||||
value.parse().map_err(|s| E::custom(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Action {
|
||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> std::result::Result<Self, D::Error> {
|
||||
deserializer.deserialize_str(ActionVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct Keybind {
|
||||
pub key: char,
|
||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -41,6 +41,7 @@ pub enum XcrabError {
|
|||
Io(std::io::Error),
|
||||
Toml(toml::de::Error),
|
||||
Var(std::env::VarError),
|
||||
FromStr(String),
|
||||
ClientDoesntExist,
|
||||
}
|
||||
|
||||
|
@ -68,6 +69,12 @@ impl From<std::env::VarError> for XcrabError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<String> for XcrabError {
|
||||
fn from(v: String) -> Self {
|
||||
Self::FromStr(v)
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref CONFIG: config::XcrabConfig = config::load_file().unwrap_or_default();
|
||||
}
|
||||
|
@ -75,10 +82,11 @@ lazy_static! {
|
|||
impl Display for XcrabError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Bread(be) => Display::fmt(&be, f)?,
|
||||
Self::Io(ie) => Display::fmt(&ie, f)?,
|
||||
Self::Toml(te) => Display::fmt(&te, f)?,
|
||||
Self::Var(ve) => Display::fmt(&ve, f)?,
|
||||
Self::Bread(be) => Display::fmt(be, f)?,
|
||||
Self::Io(ie) => Display::fmt(ie, f)?,
|
||||
Self::Toml(te) => Display::fmt(te, f)?,
|
||||
Self::Var(ve) => Display::fmt(ve, f)?,
|
||||
Self::FromStr(fe) => Display::fmt(fe, f)?,
|
||||
Self::ClientDoesntExist => Display::fmt("client didn't exist", f)?,
|
||||
}
|
||||
|
||||
|
@ -212,11 +220,7 @@ async fn process_event<Dpy: AsyncDisplay + ?Sized>(
|
|||
{
|
||||
for (&bind, action) in &CONFIG.binds {
|
||||
if bind.key == c && bind.mods == ev.state {
|
||||
// TODO: parse action into an enum & match it
|
||||
if action == "close" {
|
||||
manager.destroy_focused_client(conn).await?;
|
||||
return Ok(());
|
||||
}
|
||||
action.eval(manager, conn).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,10 +55,9 @@ pub async fn on_recv<Dpy: AsyncDisplay + ?Sized>(
|
|||
manager: &mut XcrabWindowManager,
|
||||
conn: &mut Dpy,
|
||||
) -> Result<()> {
|
||||
match &*data {
|
||||
"close" => manager.destroy_focused_client(conn).await?,
|
||||
_ => println!("{}", data),
|
||||
}
|
||||
let a: Action = data.parse()?;
|
||||
a.eval(manager, conn).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -68,18 +67,34 @@ pub enum Action {
|
|||
Close,
|
||||
}
|
||||
|
||||
impl FromStr for Action {
|
||||
impl std::str::FromStr for Action {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
#[allow(clippy::enum_glob_use)]
|
||||
use Action::*;
|
||||
let v: Vec<String> = s.split(' ').map(str::to_ascii_lowercase).collect();
|
||||
|
||||
let a = match v[0].as_str() {
|
||||
"close" => Close,
|
||||
_ => return format!("Unknown action: {}", v[0]),
|
||||
_ => return Err(format!("Unknown action: {}", v[0])),
|
||||
};
|
||||
|
||||
Ok(a)
|
||||
}
|
||||
}
|
||||
|
||||
impl Action {
|
||||
pub async fn eval<Dpy: AsyncDisplay + ?Sized>(
|
||||
&self,
|
||||
manager: &mut XcrabWindowManager,
|
||||
conn: &mut Dpy,
|
||||
) -> Result<()> {
|
||||
#[allow(clippy::enum_glob_use)]
|
||||
use Action::*;
|
||||
match self {
|
||||
Close => manager.destroy_focused_client(conn).await?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue