1use configparser::ini::Ini;
2
3use crate::private_prelude::*;
4
5pub(crate) struct Action {
6 id: String,
7 ini: Ini,
8 name: String,
9}
10
11impl Action {
12 fn get_section(id: &str) -> String {
13 format!("Desktop Action {}", id)
14 }
15
16 pub(crate) fn new(id: String, ini: Ini) -> Option<Self> {
17 Some(Self {
18 name: ini.get(&Self::get_section(&id), "Name")?,
19 id,
20 ini,
21 })
22 }
23}
24
25pub struct ActionHandle {
27 pub(crate) inner: Arc<Action>,
28 pub(crate) service: ApplicationService,
29}
30
31impl ActionHandle {
32 fn get_section(&self) -> String {
33 Action::get_section(&self.inner.id)
34 }
35
36 fn get_value(&self, key: &str) -> Option<String> {
37 self.inner.ini.get(&self.get_section(), key)
38 }
39
40 fn get_value_locale(&self, key: &str) -> Option<String> {
41 utils::get_locale_string(
42 &self.inner.ini,
43 &self.get_section(),
44 key,
45 &self.service.inner.locale,
46 )
47 }
48
49 pub fn name(&self) -> String {
53 self.inner.name.clone()
54 }
55
56 pub fn name_locale(&self) -> String {
58 self.get_value_locale("Name").unwrap_or_else(|| self.name())
59 }
60
61 pub fn icon(&self) -> Option<String> {
63 self.get_value("Icon")
64 }
65
66 pub fn icon_locale(&self) -> Option<String> {
68 self.get_value_locale("Icon").or_else(|| self.icon())
69 }
70
71 pub fn exec(&self) -> Option<String> {
73 self.get_value("Exec")
74 }
75
76 fn terminal(&self) -> bool {
77 self.inner
78 .ini
79 .getbool("Desktop Entry", "Terminal")
80 .ok()
81 .flatten()
82 .unwrap_or(false)
83 }
84
85 pub fn launch(&self) -> Result<()> {
87 utils::launch_from_exec_string(self.exec(), self.terminal())
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94 use configparser::ini::Ini;
95
96 fn new_handle(id: &str, contents: String, locale: &str) -> ActionHandle {
97 let mut ini = Ini::new();
98 ini.read(contents).unwrap();
99
100 ActionHandle {
101 inner: Arc::new(Action::new(String::from(id), ini).unwrap()),
102 service: ApplicationService::new_with_env(vec![], locale),
103 }
104 }
105 #[test]
106 fn test_properties() {
107 let contents = String::from(
108 r#"[Desktop Action Meow]
109Name=Meow
110Name[en]=Meow english
111Icon=some-icon
112Exec=ls"#,
113 );
114
115 let handle = new_handle("Meow", contents, "en");
116
117 assert_eq!(handle.name(), "Meow");
118 assert_eq!(handle.name_locale(), "Meow english");
119 assert_eq!(handle.icon().unwrap(), "some-icon");
120 assert_eq!(handle.exec().unwrap(), "ls");
121 }
122
123 #[test]
124 #[should_panic]
125 fn test_invalid() {
126 let contents = String::from(
128 r#"[Desktop Action Meow]
129Icon=some-icon
130Exec=ls"#,
131 );
132
133 new_handle("Meow", contents, "");
134 }
135}