This repository was archived by the owner on Jun 19, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathclick.rs
132 lines (119 loc) · 3.62 KB
/
click.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use std::fmt;
use serde::de::{self, Deserialize, Deserializer, Visitor};
use crate::errors::{self, ResultExt};
use crate::subprocess::{spawn_shell, spawn_shell_sync};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MouseButton {
Left,
Middle,
Right,
WheelUp,
WheelDown,
Forward,
Back,
Unknown,
/// Experemental
DoubleLeft,
}
#[derive(serde_derive::Deserialize, Debug, Clone, Default)]
pub struct ClickHandler(Vec<ClickConfigEntry>);
impl ClickHandler {
// Returns true if the block needs to be updated
pub async fn handle(&self, button: MouseButton) -> errors::Result<bool> {
Ok(match self.0.iter().find(|e| e.button == button) {
Some(entry) => {
if let Some(cmd) = &entry.cmd {
if entry.sync {
spawn_shell_sync(cmd).await
} else {
spawn_shell(cmd)
}
.or_error(|| {
format!("'{:?}' button handler: Failed to run '{}", button, cmd)
})?;
}
entry.update
}
None => true,
})
}
}
#[derive(serde_derive::Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct ClickConfigEntry {
/// Which button to handle
button: MouseButton,
/// Which command to run
#[serde(default)]
cmd: Option<String>,
/// Whether to wait for command to exit or not (default is `false`)
#[serde(default)]
sync: bool,
/// Whether to update the block on click (default is `true`)
#[serde(default = "return_true")]
update: bool,
}
fn return_true() -> bool {
true
}
impl<'de> Deserialize<'de> for MouseButton {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct MouseButtonVisitor;
impl<'de> Visitor<'de> for MouseButtonVisitor {
type Value = MouseButton;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("u64 or string")
}
// ```toml
// button = "left"
// ```
fn visit_str<E>(self, name: &str) -> Result<MouseButton, E>
where
E: de::Error,
{
use MouseButton::*;
Ok(match name {
"left" => Left,
"middle" => Middle,
"right" => Right,
"up" => WheelUp,
"down" => WheelDown,
"forward" => Forward,
"back" => Back,
// Experemental
"double_left" => DoubleLeft,
_ => Unknown,
})
}
// ```toml
// button = 1
// ```
fn visit_i64<E>(self, number: i64) -> Result<MouseButton, E>
where
E: de::Error,
{
use MouseButton::*;
Ok(match number {
1 => Left,
2 => Middle,
3 => Right,
4 => WheelUp,
5 => WheelDown,
9 => Forward,
8 => Back,
_ => Unknown,
})
}
fn visit_u64<E>(self, number: u64) -> Result<MouseButton, E>
where
E: de::Error,
{
self.visit_i64(number as i64)
}
}
deserializer.deserialize_any(MouseButtonVisitor)
}
}