lefthk_core/config/command/
execute.rs1use std::process::Stdio;
2
3use ron::ser::PrettyConfig;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 config::command::utils::denormalize_function::DenormalizeCommandFunction, errors::Error,
8 worker::Worker,
9};
10
11use super::{Command, NormalizedCommand};
12
13inventory::submit! {DenormalizeCommandFunction::new::<Execute>()}
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
16pub struct Execute(String);
17
18impl Execute {
19 pub fn new<T: ToString>(shell_command: &T) -> Self {
20 Self(shell_command.to_string())
21 }
22}
23
24impl Command for Execute {
25 fn normalize(&self) -> NormalizedCommand {
26 let serialized_string =
27 ron::ser::to_string_pretty(self, PrettyConfig::new().struct_names(true)).unwrap();
28 NormalizedCommand(serialized_string)
29 }
30
31 fn denormalize(generalized: &NormalizedCommand) -> Option<Box<Self>> {
32 ron::from_str(&generalized.0).ok()
33 }
34
35 fn execute(&self, worker: &mut Worker) -> Error {
36 worker.chord_ctx.elapsed = worker.chord_ctx.keybinds.is_some();
37 let child = std::process::Command::new("sh")
38 .arg("-c")
39 .arg(&self.0)
40 .stdin(Stdio::null())
41 .stdout(Stdio::null())
42 .stderr(Stdio::null())
43 .spawn()?;
44
45 worker.children.insert(child);
46
47 Ok(())
48 }
49
50 fn get_name(&self) -> &'static str {
51 "Execute"
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use crate::config::Command;
58
59 use super::Execute;
60
61 #[test]
62 fn normalize_process() {
63 let command = Execute::new(&"echo 'I use Arch by the way'");
64
65 let normalized = command.normalize();
66 let denormalized = Execute::denormalize(&normalized).unwrap();
67
68 assert_eq!(
69 Box::new(command),
70 denormalized,
71 "{normalized:?}, {denormalized:?}",
72 );
73 }
74}