Skip to main content

mkutils/key_map/
key_map_state.rs

1use 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}