1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use std::io;
use console::Key::*;
use console::Term;

pub struct InputHandler {
    pub line: String,
    cursor_position: usize,
    term: Term,
}

impl InputHandler {
    pub fn new(input: &str) -> Self {
        InputHandler {
            line: input.to_string(),
            cursor_position: input.len(),
            term: Term::stdout(),
        }
    }
    pub fn read_key(&mut self) -> io::Result<console::Key> {
        self.term.write_line(&format!("Search >{}", self.line))?;
        self.term.move_cursor_up(1)?;
        self.term.move_cursor_right(self.cursor_position+8)?;
        match self.term.read_key() {
            Ok(key) => {
                match key {
                    Char(c) => self.add_char(c),
                    Backspace => self.backspace_char(),
                    Del => self.del_char(),
                    ArrowLeft => self.move_left(),
                    ArrowRight => self.move_right(),
                    Home => self.move_home(),
                    End => self.move_end(),
                    _ => {}
                };
                Ok(key)
            }
            Err(_) => Ok(Escape),
        }
    }

    fn add_char(&mut self, c: char) {
        if self.cursor_position == self.line.len() {
            self.line.push(c);
            self.cursor_position = self.line.len();
        } else {
            self.line.insert(self.cursor_position, c);
        }
    }

    fn backspace_char(&mut self) {
        if self.cursor_position == self.line.len() {
            self.line.pop();
            self.cursor_position = self.line.len();
        } else {
            self.line.remove(self.cursor_position - 1);
            self.cursor_position -=1;
        }
    }

    fn del_char(&mut self) {
        if self.cursor_position == self.line.len() {
            self.line.pop();
            self.cursor_position = self.line.len();
        } else {
            self.line.remove(self.cursor_position);
        }
    }

    fn move_left(&mut self) {
        if self.cursor_position == 0 {
            self.cursor_position = 0;
        } else {
            self.cursor_position -= 1;
        }
    }
    fn move_right(&mut self) {
        if self.cursor_position < self.line.len() {
            self.cursor_position += 1;
        }
    }

    fn move_home(&mut self) {
        self.cursor_position = 0;
    }

    fn move_end(&mut self) {
        self.cursor_position = self.line.len();
    }

}

#[test]
fn test_input() {
    let mut ih = InputHandler::new("");

    ih.add_char('a');
    assert_eq!("a", ih.line);

    ih.move_home();
    ih.add_char('b');
    assert_eq!("ba", ih.line);

    ih.move_end();
    ih.add_char('c');
    assert_eq!("bac", ih.line);

    ih.move_left();
    ih.backspace_char();
    assert_eq!("bc", ih.line);

    ih.move_left();
    ih.add_char('a');
    assert_eq!("abc", ih.line);

    ih.move_right();
    ih.del_char();
    assert_eq!("ac", ih.line);
}