gcd_cli/
inputhandler.rs

1use std::io;
2use console::Key::*;
3use console::Term;
4
5pub struct InputHandler {
6    pub line: String,
7    cursor_position: usize,
8    term: Term,
9}
10
11impl InputHandler {
12    pub fn new(input: &str) -> Self {
13        InputHandler {
14            line: input.to_owned(),
15            cursor_position: input.len(),
16            term: Term::stdout(),
17        }
18    }
19
20    pub fn read_key(&mut self) -> io::Result<console::Key> {
21        self.term.write_line(&format!("Search >{}", self.line))?;
22        self.term.move_cursor_up(1)?;
23        self.term.move_cursor_right(self.cursor_position+8)?;
24        match self.term.read_key() {
25            Ok(key) => {
26                match key {
27                    Char(c) => self.add_char(c),
28                    Backspace => self.backspace_char(),
29                    Del => self.del_char(),
30                    ArrowLeft => self.move_left(),
31                    ArrowRight => self.move_right(),
32                    Home => self.move_home(),
33                    End => self.move_end(),
34                    _ => {}
35                };
36                Ok(key)
37            }
38            Err(_) => Ok(Escape),
39        }
40    }
41
42    fn add_char(&mut self, c: char) {
43        if self.cursor_position == self.line.len() {
44            self.line.push(c);
45            self.cursor_position = self.line.len();
46        } else {
47            self.line.insert(self.cursor_position, c);
48            self.cursor_position +=1;
49        }
50    }
51
52    fn backspace_char(&mut self) {
53        if self.cursor_position == self.line.len() {
54            self.line.pop();
55            self.cursor_position = self.line.len();
56        } else {
57            self.line.remove(self.cursor_position - 1);
58            self.cursor_position -=1;
59        }
60    }
61
62    fn del_char(&mut self) {
63        if self.cursor_position == self.line.len() {
64            self.line.pop();
65            self.cursor_position = self.line.len();
66        } else {
67            self.line.remove(self.cursor_position);
68        }
69    }
70
71    fn move_left(&mut self) {
72        if self.cursor_position == 0 {
73            self.cursor_position = 0;
74        } else {
75            self.cursor_position -= 1;
76        }
77    }
78    fn move_right(&mut self) {
79        if self.cursor_position < self.line.len() {
80            self.cursor_position += 1;
81        }
82    }
83
84    fn move_home(&mut self) {
85        self.cursor_position = 0;
86    }
87
88    fn move_end(&mut self) {
89        self.cursor_position = self.line.len();
90    }
91
92}
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97    #[test]
98    fn test_input() {
99        let mut ih = InputHandler::new("");
100
101        ih.add_char('a');
102        assert_eq!("a", ih.line);
103
104        ih.move_home();
105        ih.add_char('b');
106        assert_eq!("ba", ih.line);
107
108        ih.move_end();
109        ih.add_char('c');
110        assert_eq!("bac", ih.line);
111
112        ih.move_left();
113        ih.backspace_char();
114        assert_eq!("bc", ih.line);
115
116        ih.move_left();
117        ih.add_char('a');
118        assert_eq!("abc", ih.line);
119
120        ih.move_left();
121        ih.move_left();
122        ih.add_char('d');
123        assert_eq!("dabc", ih.line);
124
125        ih.move_right();
126        ih.del_char();
127        assert_eq!("dac", ih.line);
128
129        ih.move_end();
130        ih.del_char();
131        assert_eq!("da", ih.line);
132
133        ih.move_end();
134        ih.backspace_char();
135        assert_eq!("d", ih.line);
136
137        ih.move_home();
138        ih.add_char('b');
139        assert_eq!("bd", ih.line);
140        ih.add_char('c');
141        assert_eq!("bcd", ih.line);
142        ih.move_end();
143        ih.move_left();
144        ih.add_char('x');
145        ih.add_char('y');
146        ih.add_char('z');
147        assert_eq!("bcxyzd", ih.line);
148
149    }
150}