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