mkutils/key_map/
key_map_state.rs1use crate::{key_map::key_map::KeyMap, utils::Utils};
2use crossterm::event::KeyEvent;
3use std::{
4 marker::PhantomData,
5 time::{Duration, Instant},
6};
7use trie_rs::inc_search::{Answer, IncSearch, Position};
8
9pub type KeyMapIncSearch<'a, T> = IncSearch<'a, KeyEvent, T>;
10
11pub struct KeyMapState<T> {
12 reset_time: Instant,
13 reset_period: Duration,
14 position: Position,
15 phantom: PhantomData<T>,
16}
17
18impl<T: Clone> KeyMapState<T> {
19 pub const DEFAULT_RESET_PERIOD: Duration = Duration::from_millis(250);
20
21 #[must_use]
22 pub fn new(key_map: &KeyMap<T>) -> Self {
23 Self::new_with_reset_period(key_map, Self::DEFAULT_RESET_PERIOD)
24 }
25
26 #[must_use]
27 pub fn new_with_reset_period(key_map: &KeyMap<T>, reset_period: Duration) -> Self {
28 let reset_time = Instant::now();
29 let position = Self::get_key_map_trie_root_position(key_map);
30 let phantom = PhantomData;
31 let mut key_map_state = Self {
32 reset_time,
33 reset_period,
34 position,
35 phantom,
36 };
37
38 key_map_state.defer_reset_time();
39
40 key_map_state
41 }
42
43 fn defer_reset_time(&mut self) {
44 self.reset_time = Instant::now() + self.reset_period;
45 }
46
47 fn get_key_map_trie_root_position(key_map: &KeyMap<T>) -> Position {
48 key_map.trie().inc_search().into()
49 }
50
51 fn resume_inc_search<'a>(&self, key_map: &'a KeyMap<T>) -> KeyMapIncSearch<'a, T> {
52 IncSearch::resume(key_map.trie(), self.position)
53 }
54
55 fn set_position<P: Into<Position>>(&mut self, position: P) {
56 self.position = position.into();
57 }
58
59 fn set_position_to_key_map_trie_root(&mut self, key_map: &KeyMap<T>) {
60 let position = Self::get_key_map_trie_root_position(key_map);
61
62 self.set_position(position);
63 }
64
65 fn reset(&mut self, key_map: &KeyMap<T>) {
66 self.defer_reset_time();
67 self.set_position_to_key_map_trie_root(key_map);
68 }
69
70 fn get_value_from_inc_search_and_reset<'a>(
71 &mut self,
72 inc_search: &KeyMapIncSearch<'a, T>,
73 key_map: &'a KeyMap<T>,
74 ) -> Option<&'a T> {
75 let value_opt = inc_search.value();
76
77 self.reset(key_map);
78
79 value_opt
80 }
81
82 fn get_value_from_key_map_and_reset<'a>(&mut self, key_map: &'a KeyMap<T>) -> Option<&'a T> {
83 let inc_search = self.resume_inc_search(key_map);
84
85 self.get_value_from_inc_search_and_reset(&inc_search, key_map)
86 }
87
88 pub fn on_key_event<'a>(&mut self, key_map: &'a KeyMap<T>, key_event: KeyEvent) -> Option<&'a T> {
89 self.defer_reset_time();
90
91 let mut inc_search = self.resume_inc_search(key_map);
92
93 match inc_search.query(&key_event) {
94 Some(Answer::Match) => return self.get_value_from_inc_search_and_reset(&inc_search, key_map),
95 Some(Answer::PrefixAndMatch | Answer::Prefix) => self.set_position(inc_search),
96 None => self.set_position_to_key_map_trie_root(key_map),
97 }
98
99 None
100 }
101
102 pub fn on_tick<'a>(&mut self, key_map: &'a KeyMap<T>) -> Option<&'a T> {
103 if self.reset_time.has_happened() {
104 self.get_value_from_key_map_and_reset(key_map)
105 } else {
106 None
107 }
108 }
109
110 pub fn on_key_map_update(&mut self, key_map: &KeyMap<T>) {
111 self.reset(key_map);
112 }
113}