1use std::time::Instant;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum InputMode {
8 Normal,
10 Search,
12}
13
14#[derive(Debug, Clone)]
16pub struct InputState {
17 mode: InputMode,
19 pending_key: Option<char>,
21 pending_key_time: Option<Instant>,
23}
24
25impl Default for InputState {
26 fn default() -> Self {
27 Self {
28 mode: InputMode::Normal,
29 pending_key: None,
30 pending_key_time: None,
31 }
32 }
33}
34
35impl InputState {
36 pub fn new() -> Self {
38 Self::default()
39 }
40
41 pub fn mode(&self) -> InputMode {
43 self.mode
44 }
45
46 pub fn pending_key(&self) -> Option<char> {
48 self.pending_key
49 }
50
51 pub fn pending_key_time(&self) -> Option<Instant> {
53 self.pending_key_time
54 }
55
56 pub fn enter_search(&mut self) {
58 self.mode = InputMode::Search;
59 }
60
61 pub fn exit_search(&mut self) {
63 self.mode = InputMode::Normal;
64 }
65
66 pub fn is_searching(&self) -> bool {
68 self.mode == InputMode::Search
69 }
70
71 pub fn set_pending_key(
73 &mut self,
74 key: char,
75 ) {
76 self.pending_key = Some(key);
77 self.pending_key_time = Some(Instant::now());
78 }
79
80 pub fn clear_pending_key(&mut self) {
82 self.pending_key = None;
83 self.pending_key_time = None;
84 }
85
86 pub fn is_pending_key_expired(&self) -> bool {
88 if let (Some(_), Some(time)) = (self.pending_key, self.pending_key_time) {
89 time.elapsed() > std::time::Duration::from_secs(2)
90 } else {
91 false
92 }
93 }
94}
95
96#[cfg(test)]
97#[path = "input_tests.rs"]
98mod input_tests;