1use core::fmt::Debug;
2use core::ops::Index;
3
4use serde::Deserialize;
5
6use crate::input;
7use crate::key;
8
9#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
11pub struct Ref(pub u8);
12
13#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
15pub struct Config {
16 #[serde(default = "default_timeout")]
21 pub timeout: u16,
22}
23
24pub const DEFAULT_TIMEOUT: u16 = 200;
26
27fn default_timeout() -> u16 {
28 DEFAULT_TIMEOUT
29}
30
31pub const DEFAULT_CONFIG: Config = Config {
33 timeout: DEFAULT_TIMEOUT,
34};
35
36impl Config {
37 pub const fn new() -> Self {
39 DEFAULT_CONFIG
40 }
41}
42
43impl Default for Config {
44 fn default() -> Self {
46 DEFAULT_CONFIG
47 }
48}
49
50#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
52pub struct Key<R, const MAX_TAP_DANCE_DEFINITIONS: usize> {
53 #[serde(bound(deserialize = "R: Deserialize<'de>"))]
55 #[serde(deserialize_with = "deserialize_definitions")]
56 definitions: [Option<R>; MAX_TAP_DANCE_DEFINITIONS],
57}
58
59fn deserialize_definitions<'de, R, D, const MAX_TAP_DANCE_DEFINITIONS: usize>(
61 deserializer: D,
62) -> Result<[Option<R>; MAX_TAP_DANCE_DEFINITIONS], D::Error>
63where
64 R: Deserialize<'de>,
65 D: serde::Deserializer<'de>,
66{
67 let defs_vec: heapless::Vec<Option<R>, MAX_TAP_DANCE_DEFINITIONS> =
68 Deserialize::deserialize(deserializer)?;
69
70 match defs_vec.into_array() {
71 Ok(arr) => Ok(arr),
72 Err(_) => Err(serde::de::Error::custom(
73 "Unable to deserialize tap_dance definitions",
74 )),
75 }
76}
77
78impl<R: Copy, const MAX_TAP_DANCE_DEFINITIONS: usize> Key<R, MAX_TAP_DANCE_DEFINITIONS> {
79 pub const fn new(
81 definitions: [Option<R>; MAX_TAP_DANCE_DEFINITIONS],
82 ) -> Key<R, MAX_TAP_DANCE_DEFINITIONS> {
83 Key { definitions }
84 }
85
86 pub const fn from_definitions(defs: &[R]) -> Self {
88 let mut definitions: [Option<R>; MAX_TAP_DANCE_DEFINITIONS] =
89 [None; MAX_TAP_DANCE_DEFINITIONS];
90 let mut idx = 0;
91 while idx < definitions.len() && idx < defs.len() {
92 definitions[idx] = Some(defs[idx]);
93 idx += 1;
94 }
95 Self::new(definitions)
96 }
97}
98
99#[derive(Debug, Clone, Copy, PartialEq)]
101pub struct Context {
102 config: Config,
103}
104
105impl Context {
106 pub const fn from_config(config: Config) -> Context {
108 Context { config }
109 }
110
111 pub fn reset(&mut self) {
113 *self = Self::from_config(self.config);
114 }
115}
116
117#[derive(Debug, Clone, Copy, PartialEq)]
119pub struct TapDanceResolution(u8);
120
121#[derive(Debug, Clone, Copy, PartialEq)]
123pub enum Event {
124 NextPressTimeout(u8),
126}
127
128#[derive(Debug, Clone, Copy, PartialEq)]
130pub struct PendingKeyState {
131 press_count: u8,
132}
133
134impl PendingKeyState {
135 fn new() -> PendingKeyState {
137 PendingKeyState { press_count: 0 }
138 }
139
140 fn handle_event(
141 &mut self,
142 context: &Context,
143 keymap_index: u16,
144 event: key::Event<Event>,
145 ) -> (Option<TapDanceResolution>, key::KeyEvents<Event>) {
146 match event {
147 key::Event::Key {
148 key_event: Event::NextPressTimeout(press_timed_out),
149 keymap_index: ev_kmi,
150 } if ev_kmi == keymap_index && press_timed_out == self.press_count => (
151 Some(TapDanceResolution(self.press_count)),
152 key::KeyEvents::no_events(),
153 ),
154
155 key::Event::Input(input::Event::Press {
156 keymap_index: ev_kmi,
157 }) if ev_kmi == keymap_index => {
158 self.press_count += 1;
159
160 let Context { config } = context;
161 let timeout_ev = Event::NextPressTimeout(self.press_count);
162
163 let key_ev = key::Event::Key {
164 keymap_index,
165 key_event: timeout_ev,
166 };
167 let pke = key::KeyEvents::scheduled_event(key::ScheduledEvent::after(
168 config.timeout,
169 key_ev,
170 ));
171
172 (None, pke)
173 }
174
175 _ => (None, key::KeyEvents::no_events()),
176 }
177 }
178}
179
180#[derive(Debug, Clone, Copy, PartialEq)]
182pub struct KeyState;
183
184#[derive(Debug, Clone, Copy, PartialEq)]
186pub struct System<
187 R,
188 Keys: Index<usize, Output = Key<R, MAX_TAP_DANCE_DEFINITIONS>>,
189 const MAX_TAP_DANCE_DEFINITIONS: usize,
190> {
191 keys: Keys,
192}
193
194impl<
195 R,
196 Keys: Index<usize, Output = Key<R, MAX_TAP_DANCE_DEFINITIONS>>,
197 const MAX_TAP_DANCE_DEFINITIONS: usize,
198 > System<R, Keys, MAX_TAP_DANCE_DEFINITIONS>
199{
200 pub const fn new(key_data: Keys) -> Self {
202 Self { keys: key_data }
203 }
204}
205
206impl<
207 R: Copy + Debug,
208 Keys: Debug + Index<usize, Output = Key<R, MAX_TAP_DANCE_DEFINITIONS>>,
209 const MAX_TAP_DANCE_DEFINITIONS: usize,
210 > key::System<R> for System<R, Keys, MAX_TAP_DANCE_DEFINITIONS>
211{
212 type Ref = Ref;
213 type Context = Context;
214 type Event = Event;
215 type PendingKeyState = PendingKeyState;
216 type KeyState = KeyState;
217
218 fn new_pressed_key(
219 &self,
220 keymap_index: u16,
221 context: &Self::Context,
222 _key_ref: Ref,
223 ) -> (
224 key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
225 key::KeyEvents<Self::Event>,
226 ) {
227 let td_pks = PendingKeyState::new();
228 let pk = key::PressedKeyResult::Pending(td_pks);
229
230 let timeout_ev = Event::NextPressTimeout(0);
231 let key_ev = key::Event::Key {
232 keymap_index,
233 key_event: timeout_ev,
234 };
235 let pke = key::KeyEvents::scheduled_event(key::ScheduledEvent::after(
236 context.config.timeout,
237 key_ev,
238 ));
239
240 (pk, pke)
241 }
242
243 fn update_pending_state(
244 &self,
245 pending_state: &mut Self::PendingKeyState,
246 keymap_index: u16,
247 context: &Self::Context,
248 Ref(key_index): Ref,
249 event: key::Event<Self::Event>,
250 ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
251 let key = &self.keys[key_index as usize];
252 let (maybe_resolution, pke) = pending_state.handle_event(context, keymap_index, event);
253
254 if let Some(TapDanceResolution(idx)) = maybe_resolution {
255 if let Some(new_key_ref) = key.definitions[idx as usize] {
256 (
257 Some(key::NewPressedKey::key(new_key_ref)),
258 pke.into_events(),
259 )
260 } else {
261 (None, pke.into_events())
262 }
263 } else {
264 let definition_count = key.definitions.iter().filter(|o| o.is_some()).count();
266 if pending_state.press_count as usize >= definition_count - 1 {
267 let idx = definition_count - 1;
268 if let Some(new_key_ref) = key.definitions[idx] {
269 (
270 Some(key::NewPressedKey::key(new_key_ref)),
271 pke.into_events(),
272 )
273 } else {
274 (None, pke.into_events())
275 }
276 } else {
277 (None, pke.into_events())
278 }
279 }
280 }
281
282 fn update_state(
283 &self,
284 _key_state: &mut Self::KeyState,
285 _ref: &Self::Ref,
286 _context: &Self::Context,
287 _keymap_index: u16,
288 _event: key::Event<Self::Event>,
289 ) -> key::KeyEvents<Self::Event> {
290 panic!() }
292
293 fn key_output(
294 &self,
295 _key_ref: &Self::Ref,
296 _key_state: &Self::KeyState,
297 ) -> Option<key::KeyOutput> {
298 panic!() }
300}
301
302#[cfg(test)]
303mod tests {
304 use super::*;
305
306 #[test]
307 fn test_sizeof_ref() {
308 assert_eq!(1, core::mem::size_of::<Ref>());
309 }
310
311 #[test]
312 fn test_sizeof_event() {
313 assert_eq!(1, core::mem::size_of::<Event>());
314 }
315}