1#[derive(Default)]
22pub struct Plugin {
23 pub status_bar: StatusBar,
24 pub sub_menu: Option<SubMenu>,
25}
26
27#[derive(Default, Debug, Clone)]
30pub struct Line {
31 text: String,
32 href: String,
33 color: String,
34 font: String,
35 size: i64,
36 terminal: bool,
37 refresh: bool,
38 drop_down: bool,
39 length: i64,
40 trim: bool,
41 alternate: bool,
42 emojize: bool,
43 ansi: bool,
44 bash: String,
45 params: Vec<String>,
46 template_image: String,
47 image: String,
48 hr: bool,
49}
50
51#[derive(Default, Debug)]
53pub struct Style {
54 pub color: String,
55 pub font: String,
56 pub size: i64,
57 pub length: i64,
58 pub trim: bool,
59 pub emojize: bool,
60 pub ansi: bool,
61}
62
63#[derive(Default, Debug)]
65pub struct Cmd {
66 pub bash: String,
67 pub params: Vec<String>,
68 pub terminal: bool,
69 pub refresh: bool,
70}
71
72#[derive(Default, Debug)]
75pub struct StatusBar {
76 pub lines: Vec<Line>,
77}
78
79pub struct SubMenu {
83 pub level: i64,
84 pub lines: Vec<SubMenuItem>,
85}
86
87pub enum SubMenuItem {
89 Line(Line),
90 SubMenu(Box<SubMenu>),
91}
92
93impl Plugin {
94 pub fn new() -> Self {
96 Plugin::default()
97 }
98
99 pub fn set_status_line(&mut self, line: Line) -> &mut Self {
100 self.status_bar.lines.push(line);
101 self
102 }
103
104 pub fn set_sub_menu(&mut self, sub_menu: SubMenu) -> &mut Self {
105 self.sub_menu = Some(sub_menu);
106 self
107 }
108
109 pub fn render(&self) {
110 print!("{}", self.to_string());
111 }
112}
113
114impl std::string::ToString for Plugin {
115 fn to_string(&self) -> String {
116 let mut output = String::from("");
117 for line in self.status_bar.lines.iter().as_ref() {
118 let line_str = line.to_string();
119 output = format!("{}{}\n", output, line_str);
120 }
121 output = format!("{}---\n", output);
122 if self.sub_menu.is_some() {
123 let curr_sm = self.sub_menu.as_ref().unwrap();
124 output = format!("{}{}", output, render_sub_menu(curr_sm));
125 }
126
127 return output;
128 }
129}
130
131impl SubMenu {
132 pub fn new() -> Self {
134 SubMenu {
135 level: 0,
136 lines: vec![],
137 }
138 }
139 pub fn add_line(&mut self, line: Line) -> &mut Self {
142 self.lines.push(SubMenuItem::Line(line));
143 self
144 }
145
146 pub fn add_sub_menu(&mut self, sub_menu: SubMenu) -> &mut Self {
148 self.lines.push(SubMenuItem::SubMenu(Box::new(sub_menu)));
149 self
150 }
151
152 pub fn add_hr(&mut self) -> &mut Self {
155 let line = Line {
156 text: "---".to_string(),
157 hr: true,
158 ..Default::default()
159 };
160
161 self.lines.push(SubMenuItem::Line(line));
162 self
163 }
164}
165
166impl Line {
167 pub fn new<T: Into<String>>(text: T) -> Self {
169 Line {
170 text: text.into(),
171 ..Default::default()
172 }
173 }
174 pub fn set_text<T: Into<String>>(&mut self, text: T) -> &mut Self {
176 self.text = text.into();
177 self
178 }
179
180 pub fn set_style(&mut self, style: Style) -> &mut Self {
182 self.color = style.color;
183 self.font = style.font;
184 self.size = style.size;
185 self.length = style.length;
186 self.trim = style.trim;
187 self.emojize = style.emojize;
188 self.ansi = style.ansi;
189 self
190 }
191
192 pub fn set_command(&mut self, cmd: Cmd) -> &mut Self {
195 self.bash = cmd.bash;
196 self.params = cmd.params;
197 self.terminal = cmd.terminal;
198 self.refresh = cmd.refresh;
199 self
200 }
201
202 pub fn set_href<T: Into<String>>(&mut self, href: T) -> &mut Self {
204 self.href = href.into();
205 self
206 }
207 pub fn set_color<T: Into<String>>(&mut self, color: T) -> &mut Self {
209 self.color = color.into();
210 self
211 }
212
213 pub fn set_font<T: Into<String>>(&mut self, font: T) -> &mut Self {
215 self.font = font.into();
216 self
217 }
218
219 pub fn set_size(&mut self, size: i64) -> &mut Self {
221 self.size = size;
222 self
223 }
224
225 pub fn set_bash<T: Into<String>>(&mut self, bash: T) -> &mut Self {
227 self.bash = bash.into();
228 self
229 }
230 pub fn set_params(&mut self, params: Vec<String>) -> &mut Self {
232 self.params = params;
233 self
234 }
235
236 pub fn set_terminal(&mut self, terminal: bool) -> &mut Self {
239 self.terminal = terminal;
240 self
241 }
242
243 pub fn set_refresh(&mut self, refresh: bool) -> &mut Self {
247 self.refresh = refresh;
248 self
249 }
250
251 pub fn set_drop_down(&mut self, drop_down: bool) -> &mut Self {
254 self.drop_down = drop_down;
255 self
256 }
257
258 pub fn set_length(&mut self, length: i64) -> &mut Self {
261 self.length = length;
262 self
263 }
264
265 pub fn set_trim(&mut self, trim: bool) -> &mut Self {
268 self.trim = trim;
269 self
270 }
271
272 pub fn set_alternate(&mut self, alternate: bool) -> &mut Self {
275 self.alternate = alternate;
276 self
277 }
278
279 pub fn set_emojize(&mut self, emojize: bool) -> &mut Self {
281 self.emojize = emojize;
282 self
283 }
284
285 pub fn set_ansi(&mut self, ansi: bool) -> &mut Self {
287 self.ansi = ansi;
288 self
289 }
290}
291
292impl std::string::ToString for Line {
293 fn to_string(&self) -> String {
294 let mut res = vec![self.text.to_string()];
295 let mut options: Vec<String> = vec!["|".to_string()];
296 options.append(&mut render_style_options(self));
297 options.append(&mut render_misc_options(self));
298 options.append(&mut render_command_options(self));
299
300 if options.len() > 1 {
301 res.append(&mut options);
302 }
303
304 return res.join(" ");
305 }
306}
307
308impl Style {
309 pub fn new() -> Self {
311 Style::default()
312 }
313}
314
315fn render_sub_menu(sub_menu: &SubMenu) -> String {
316 let mut output = String::new();
317 let mut prefix = String::new();
318
319 if sub_menu.level > 0 {
320 prefix = format!("{} ", "--".repeat(sub_menu.level as usize))
321 }
322 for line in sub_menu.lines.iter().as_ref() {
323 match line {
324 SubMenuItem::Line(current_line) => {
325 if current_line.hr {
326 output = format!("{}{}{}\n", output, prefix.trim(), current_line.to_string());
327 } else {
328 output = format!("{}{}{}\n", output, prefix, current_line.to_string());
329 }
330 }
331 SubMenuItem::SubMenu(current_sub_m) => {
332 output = format!("{}{}", output, render_sub_menu(¤t_sub_m))
333 }
334 }
335 }
336
337 output
338}
339
340fn render_misc_options(line: &Line) -> Vec<String> {
341 let mut misc_opts = vec![];
342
343 if line.href != "" {
344 misc_opts.push(format!("href='{}'", line.href));
345 }
346 if line.drop_down {
347 misc_opts.push(format!("dropdown='{}'", line.drop_down));
348 }
349 if line.alternate {
350 misc_opts.push(format!("alternate='{}'", line.alternate));
351 }
352
353 misc_opts
354}
355
356fn render_style_options(line: &Line) -> Vec<String> {
357 let mut style_opts = vec![];
358 if line.color != "" {
359 style_opts.push(format!(r#"color="{}""#, line.color));
360 }
361 if line.font != "" {
362 style_opts.push(format!(r#"font="{}""#, line.font));
363 }
364 if line.size > 0 {
365 style_opts.push(format!("size={}", line.size));
366 }
367 if line.length > 0 {
368 style_opts.push(format!("length={}", line.length));
369 }
370 if line.trim {
371 style_opts.push(format!("trim={}", line.trim));
372 }
373 if line.emojize {
374 style_opts.push(format!("emojize={}", line.emojize));
375 }
376 if line.ansi {
377 style_opts.push(format!("ansi={}", line.ansi));
378 }
379
380 style_opts
381}
382
383fn render_command_options(line: &Line) -> Vec<String> {
384 let mut command_opts = vec![];
385 if line.bash != "" {
386 command_opts.push(format!(r#"bash="{}""#, line.bash));
387 }
388
389 if line.params.len() > 0 {
390 for i in 0..line.params.len() {
391 command_opts.push(format!("param{}={}", i, line.params[i]));
392 }
393 }
394 if line.terminal {
395 command_opts.push(format!("terminal={}", line.terminal));
396 }
397 if line.refresh {
398 command_opts.push(format!("refresh={}", line.refresh));
399 }
400
401 command_opts
402}
403
404#[test]
405fn test_render_command_options() {
406 let mut line = Line::new("here is a test".to_string());
407 line.set_bash("echo test".to_string())
408 .set_params(vec!["params1".to_string(), "params2".to_string()])
409 .set_refresh(true);
410 let resp = render_command_options(&line);
411
412 assert_eq!(resp[0], r#"bash="echo test""#.to_string());
413 assert_eq!(resp[1], r#"param0=params1"#.to_string());
414 assert_eq!(resp[2], r#"param1=params2"#.to_string());
415 assert_eq!(resp[3], "refresh=true".to_string());
416}
417
418#[test]
419fn test_line_to_string() {
420 let mut line = Line::new("here is a test".to_string());
421 line.set_bash("echo test".to_string())
422 .set_color("red".to_string())
423 .set_params(vec!["params1".to_string(), "params2".to_string()])
424 .set_refresh(true);
425 let resp = line.to_string();
426
427 assert_eq!(resp, r#"here is a test | color="red" bash="echo test" param0=params1 param1=params2 refresh=true"#.to_string());
428}