gcd_cli/
outputhandler.rs

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    // not implemented yet, needs to be implemented in console first
105    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}