1use console::Term;
2use std::io;
3
4pub struct OutputHandler {
5 projects_dir: String,
6 cur: usize,
7 term: Term,
8 projects: Vec<String>,
9}
10
11impl OutputHandler {
12 pub fn new(projects_dir: String) -> Self {
13 OutputHandler {
14 projects_dir,
15 cur: 0,
16 term: Term::stdout(),
17 projects: vec![],
18 }
19 }
20
21 pub fn up(&mut self) -> io::Result<usize> {
22 if self.cur == 0 {
23 self.cur = 0;
24 } else {
25 self.cur -= 1;
26 }
27 self.show()
28 }
29
30 pub fn down(&mut self) -> io::Result<usize> {
31 if self.cur < self.projects.len() - 1 {
32 self.cur += 1;
33 }
34 self.show()
35 }
36
37 fn show(&mut self) -> io::Result<usize> {
38 self.clear_results()?;
39 let mut index = 0;
40 self.term.move_cursor_down(1)?;
41 for project in self
42 .projects
43 .iter()
44 .map(|p| p.replace(&self.projects_dir.clone(), ""))
45 {
46 if index == self.cur {
47 term_extra::set_foreground_color(2)?;
48 self.term.write_line(&format!(" > {}", project))?;
49 term_extra::turn_off_all_attributes()?;
50 } else {
51 self.term.write_line(&format!(" {}", project))?;
52 }
53 index += 1;
54 if index > 20 {
55 break;
56 }
57 }
58 self.term.move_cursor_up(index + 1)?;
59 Ok(index)
60 }
61
62 pub fn show_results(&mut self, projects: Vec<String>) -> io::Result<usize> {
63 self.projects = projects.iter().map(|p| p.to_owned()).collect();
64 self.cur = 0;
65 self.show()
66 }
67
68 pub fn get_selected(&mut self) -> Option<String> {
69 let _ = self.clear_results();
70 if self.projects.len() > self.cur {
71 return Some(self.projects[self.cur].to_owned());
72 }
73 None
74 }
75
76 pub fn clear_results(&mut self) -> io::Result<()> {
77 self.term.clear_to_end_of_screen()?;
78 Ok(())
79 }
80}
81
82#[cfg(unix)]
83mod term_extra {
84 use std::io;
85 use std::io::Write;
86
87 pub fn set_foreground_color(code: usize) -> io::Result<()> {
88 io::stdout().write_all(&format!("\x1b[{}m", code).as_bytes())?;
89 io::stdout().flush()?;
90 Ok(())
91 }
92
93 pub fn turn_off_all_attributes() -> io::Result<()> {
94 io::stdout().write_all(&format!("\x1b[0m").as_bytes())?;
95 io::stdout().flush()?;
96 Ok(())
97 }
98}
99
100#[cfg(windows)]
101mod term_extra {
102 use std::io;
103
104 pub fn set_foreground_color(_code: usize) -> io::Result<()> {
106 Ok(())
107 }
108
109 pub fn turn_off_all_attributes() -> io::Result<()> {
110 Ok(())
111 }
112}