1use core::fmt::Debug;
2
3use serde::Deserialize;
4
5use crate::input;
6use crate::key;
7use crate::keymap;
8
9pub use crate::init::MAX_TAP_DANCE_DEFINITIONS;
10
11#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
13pub struct Config {
14 #[serde(default = "default_timeout")]
16 pub timeout: u16,
17}
18
19fn default_timeout() -> u16 {
20 DEFAULT_CONFIG.timeout
21}
22
23pub const DEFAULT_CONFIG: Config = Config { timeout: 200 };
25
26impl Default for Config {
27 fn default() -> Self {
29 DEFAULT_CONFIG
30 }
31}
32
33#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
35pub struct Key<K: key::Key> {
36 definitions: [Option<K>; MAX_TAP_DANCE_DEFINITIONS],
38}
39
40impl<K: key::Key + Copy> Key<K> {
41 pub const fn new(definitions: [Option<K>; MAX_TAP_DANCE_DEFINITIONS]) -> Key<K> {
43 Key { definitions }
44 }
45
46 pub const fn from_definitions(defs: &[K]) -> Self {
48 let mut definitions: [Option<K>; MAX_TAP_DANCE_DEFINITIONS] =
49 [None; MAX_TAP_DANCE_DEFINITIONS];
50 let mut idx = 0;
51 while idx < definitions.len() && idx < defs.len() {
52 definitions[idx] = Some(defs[idx]);
53 idx += 1;
54 }
55 Self::new(definitions)
56 }
57}
58
59impl<K: key::Key> Key<K> {
60 fn new_pressed_key(
61 &self,
62 context: &K::Context,
63 key_path: key::KeyPath,
64 ) -> (
65 key::PressedKeyResult<K::PendingKeyState, K::KeyState>,
66 key::KeyEvents<K::Event>,
67 )
68 where
69 for<'ctx> &'ctx K::Context: Into<&'ctx Context>,
70 for<'ctx> &'ctx K::Context: Into<&'ctx keymap::KeymapContext>,
71 Event: Into<K::Event>,
72 PendingKeyState: Into<K::PendingKeyState>,
73 {
74 let keymap_index: u16 = key_path[0];
75
76 let td_pks = PendingKeyState::new();
77 let pk = key::PressedKeyResult::Pending(key_path, td_pks.into());
78
79 let &Context { config, .. } = context.into();
80 let timeout_ev = Event::NextPressTimeout(0);
81 let key_ev = key::Event::Key {
82 keymap_index,
83 key_event: timeout_ev,
84 };
85 let pke =
86 key::KeyEvents::scheduled_event(key::ScheduledEvent::after(config.timeout, key_ev));
87
88 (pk, pke.into_events())
89 }
90}
91
92impl<
93 K: key::Key<
94 Context = crate::init::Context,
95 Event = crate::init::Event,
96 PendingKeyState = crate::init::PendingKeyState,
97 KeyState = crate::init::KeyState,
98 >,
99 > key::Key for Key<K>
100{
101 type Context = crate::init::Context;
102 type Event = crate::init::Event;
103 type PendingKeyState = crate::init::PendingKeyState;
104 type KeyState = crate::init::KeyState;
105
106 fn new_pressed_key(
107 &self,
108 context: &Self::Context,
109 key_path: key::KeyPath,
110 ) -> (
111 key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>,
112 key::KeyEvents<Self::Event>,
113 ) {
114 self.new_pressed_key(context, key_path.clone())
115 }
116
117 fn handle_event(
118 &self,
119 pending_state: &mut Self::PendingKeyState,
120 context: &Self::Context,
121 key_path: key::KeyPath,
122 event: key::Event<Self::Event>,
123 ) -> (
124 Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
125 key::KeyEvents<Self::Event>,
126 ) {
127 let keymap_index = key_path[0];
128 let td_pks_res: Result<&mut PendingKeyState, _> = pending_state.try_into();
129 if let Ok(td_pks) = td_pks_res {
130 if let Ok(td_ev) = event.try_into_key_event(|e| e.try_into()) {
131 let (maybe_resolution, pke) =
132 td_pks.handle_event(context.into(), keymap_index, td_ev);
133
134 if let Some(TapDanceResolution(idx)) = maybe_resolution {
135 let nk = (&self.definitions[idx as usize]).as_ref().unwrap();
136
137 let (pkr, pke) = nk.new_pressed_key(context, key_path);
138 let pkr = pkr.add_path_item(idx as u16);
140
141 (Some(pkr), pke)
142 } else {
143 let definition_count = self.definitions.iter().filter(|o| o.is_some()).count();
145 if td_pks.press_count as usize >= definition_count - 1 {
146 let idx = definition_count - 1;
147 let nk = (&self.definitions[idx]).as_ref().unwrap();
148 let (pkr, pke) = nk.new_pressed_key(context, key_path);
149 let pkr = pkr.add_path_item(idx as u16);
151
152 (Some(pkr), pke)
153 } else {
154 (None, pke.into_events())
155 }
156 }
157 } else {
158 (None, key::KeyEvents::no_events())
159 }
160 } else {
161 (None, key::KeyEvents::no_events())
162 }
163 }
164
165 fn lookup(
166 &self,
167 path: &[u16],
168 ) -> &dyn key::Key<
169 Context = Self::Context,
170 Event = Self::Event,
171 PendingKeyState = Self::PendingKeyState,
172 KeyState = Self::KeyState,
173 > {
174 match path {
175 [] => self,
176 [idx, path @ ..] => match &self.definitions[*idx as usize] {
178 Some(key) => key.lookup(path),
179 None => panic!(),
180 },
181 }
182 }
183}
184
185#[derive(Debug, Clone, Copy, PartialEq)]
187pub struct Context {
188 config: Config,
189}
190
191pub const DEFAULT_CONTEXT: Context = Context::from_config(DEFAULT_CONFIG);
193
194impl Context {
195 pub const fn from_config(config: Config) -> Context {
197 Context { config }
198 }
199}
200
201#[derive(Debug, Clone, Copy, PartialEq)]
203pub struct TapDanceResolution(u8);
204
205#[derive(Debug, Clone, Copy, PartialEq)]
207pub enum Event {
208 NextPressTimeout(u8),
210}
211
212#[derive(Debug, Clone, PartialEq)]
214pub struct PendingKeyState {
215 press_count: u8,
216}
217
218impl PendingKeyState {
219 fn new() -> PendingKeyState {
221 PendingKeyState { press_count: 0 }
222 }
223
224 fn handle_event(
225 &mut self,
226 context: &Context,
227 keymap_index: u16,
228 event: key::Event<Event>,
229 ) -> (Option<TapDanceResolution>, key::KeyEvents<Event>) {
230 match event {
231 key::Event::Key {
232 key_event: Event::NextPressTimeout(press_timed_out),
233 keymap_index: ev_kmi,
234 } if ev_kmi == keymap_index && press_timed_out == self.press_count => (
235 Some(TapDanceResolution(self.press_count)),
236 key::KeyEvents::no_events(),
237 ),
238
239 key::Event::Input(input::Event::Press {
240 keymap_index: ev_kmi,
241 }) if ev_kmi == keymap_index => {
242 self.press_count += 1;
243
244 let Context { config } = context;
245 let timeout_ev = Event::NextPressTimeout(self.press_count);
246
247 let key_ev = key::Event::Key {
248 keymap_index,
249 key_event: timeout_ev,
250 };
251 let pke = key::KeyEvents::scheduled_event(key::ScheduledEvent::after(
252 config.timeout,
253 key_ev,
254 ));
255
256 (None, pke)
257 }
258
259 _ => (None, key::KeyEvents::no_events()),
260 }
261 }
262}