hyprshell_core_lib/util/
exec.rs1#[derive(Debug, Clone)]
2pub enum ExecType {
3 Flatpak(Box<str>, Box<str>),
4 PWA(Box<str>, Box<str>),
5 FlatpakPWA(Box<str>, Box<str>),
6 Absolute(Box<str>, Box<str>),
7 AppImage(Box<str>, Box<str>),
8 Relative(Box<str>),
9}
10
11const UNKNOWN_EXEC: &str = "unknown";
12
13#[must_use]
14pub fn analyse_exec(exec: &str) -> ExecType {
15 let exec_trim = exec.replace(['\'', '"'], "");
16 if exec.contains("--app-id=") && exec.contains("--profile-directory=") {
18 if exec.contains("flatpak run") || exec.contains("flatpak 'run'") {
20 let browser_exec_in_flatpak = exec_trim
21 .split_whitespace()
22 .find(|s| s.contains("--command="))
23 .and_then(|s| {
24 s.split('=')
25 .next_back()
26 .and_then(|s| s.split('/').next_back())
27 })
28 .unwrap_or(UNKNOWN_EXEC);
29 let flatpak_identifier = exec_trim
30 .split_whitespace()
31 .skip(2)
32 .find(|arg| !arg.starts_with("--"))
33 .unwrap_or(UNKNOWN_EXEC);
34 ExecType::FlatpakPWA(
35 Box::from(flatpak_identifier),
36 Box::from(browser_exec_in_flatpak),
37 )
38 } else {
39 let browser_exec = exec
41 .split_whitespace()
42 .next()
43 .and_then(|s| s.split('/').next_back())
44 .unwrap_or(UNKNOWN_EXEC);
45 let browser_full_exec = exec.split_whitespace().next().unwrap_or(UNKNOWN_EXEC);
46 ExecType::PWA(Box::from(browser_exec), Box::from(browser_full_exec))
47 }
48 } else if exec.contains("flatpak run") || exec.contains("flatpak 'run'") {
50 let command_in_flatpak = exec_trim
51 .split_whitespace()
52 .find(|s| s.contains("--command="))
53 .and_then(|s| {
54 s.split('=')
55 .next_back()
56 .and_then(|s| s.split('/').next_back())
57 })
58 .unwrap_or(UNKNOWN_EXEC);
59 let flatpak_identifier = exec_trim
60 .split_whitespace()
61 .skip(2)
62 .find(|arg| !arg.starts_with("--"))
63 .unwrap_or(UNKNOWN_EXEC);
64 ExecType::Flatpak(Box::from(flatpak_identifier), Box::from(command_in_flatpak))
65 } else if exec_trim.contains(".AppImage") {
66 let appimage_name = exec_trim
68 .split_whitespace()
69 .next()
70 .and_then(|s| s.split('/').next_back())
71 .and_then(|s| s.split('_').next())
72 .unwrap_or(UNKNOWN_EXEC);
73 ExecType::AppImage(Box::from(appimage_name), Box::from(exec))
74 } else if exec_trim.starts_with('/') {
75 let exec_name = exec_trim
76 .split_whitespace()
77 .next()
78 .and_then(|s| s.split('/').next_back())
79 .unwrap_or(UNKNOWN_EXEC);
80 ExecType::Absolute(Box::from(exec_name), Box::from(exec))
81 } else {
82 ExecType::Relative(Box::from(exec_trim))
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn test_relative_exec() {
92 assert!(matches!(
93 analyse_exec("nautilus --new-window"),
94 ExecType::Relative(ref s) if &**s == "nautilus --new-window"
95 ));
96 }
97
98 #[test]
99 fn test_flatpak_pwa_exec() {
100 assert!(matches!(
101 analyse_exec(
102 "flatpak 'run' '--command=/app/bin/chromium' 'org.chromium.Chromium' '--profile-directory=Default' '--app-id=awf'"
103 ),
104 ExecType::FlatpakPWA(ref id, ref browser) if &**id == "org.chromium.Chromium" && &**browser == "chromium"
105 ));
106 }
107
108 #[test]
109 fn test_appimage_exec() {
110 assert!(matches!(
111 analyse_exec(
112 "/home/user/Applications/ungoogled-chromium_71.0.3578.98-2_linux_awf.AppImage %u"
113 ),
114 ExecType::AppImage(ref name, ref path) if &**name == "ungoogled-chromium" && &**path == "/home/user/Applications/ungoogled-chromium_71.0.3578.98-2_linux_awf.AppImage %u"
115 ));
116 }
117
118 #[test]
119 fn test_absolute_pwa_exec() {
120 assert!(matches!(
121 analyse_exec(
122 "/opt/google/chrome/google-chrome --profile-directory=Default --app-id=awf"
123 ),
124 ExecType::PWA(ref browser, ref path) if &**browser == "google-chrome" && &**path == "/opt/google/chrome/google-chrome"
125 ));
126 }
127
128 #[test]
129 fn test_flatpak_exec() {
130 assert!(matches!(
131 analyse_exec("flatpak run org.mozilla.firefox"),
132 ExecType::Flatpak(ref id, ref command) if &**id == "org.mozilla.firefox" && &**command == "unknown"
133 ));
134 }
135
136 #[test]
137 fn test_absolute_exec() {
138 assert!(matches!(
139 analyse_exec("/usr/bin/firefox"),
140 ExecType::Absolute(ref name, ref path) if &**name == "firefox" && &**path == "/usr/bin/firefox"
141 ));
142 }
143}