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
109#[derive(Debug, Clone, Copy, PartialEq)]
111pub struct TapDanceResolution(u8);
112
113#[derive(Debug, Clone, Copy, PartialEq)]
115pub enum Event {
116 NextPressTimeout(u8),
118}
119
120#[derive(Debug, Clone, Copy, PartialEq)]
122pub struct PendingKeyState {
123 press_count: u8,
124}
125
126impl PendingKeyState {
127 fn new() -> PendingKeyState {
129 PendingKeyState { press_count: 0 }
130 }
131
132 fn handle_event(
133 &mut self,
134 context: &Context,
135 keymap_index: u16,
136 event: key::Event<Event>,
137 ) -> (Option<TapDanceResolution>, key::KeyEvents<Event>) {
138 match event {
139 key::Event::Key {
140 key_event: Event::NextPressTimeout(press_timed_out),
141 keymap_index: ev_kmi,
142 } if ev_kmi == keymap_index && press_timed_out == self.press_count => (
143 Some(TapDanceResolution(self.press_count)),
144 key::KeyEvents::no_events(),
145 ),
146
147 key::Event::Input(input::Event::Press {
148 keymap_index: ev_kmi,
149 }) if ev_kmi == keymap_index => {
150 self.press_count += 1;
151
152 let Context { config } = context;
153 let timeout_ev = Event::NextPressTimeout(self.press_count);
154
155 let key_ev = key::Event::Key {
156 keymap_index,
157 key_event: timeout_ev,
158 };
159 let pke = key::KeyEvents::scheduled_event(key::ScheduledEvent::after(
160 config.timeout,
161 key_ev,
162 ));
163
164 (None, pke)
165 }
166
167 _ => (None, key::KeyEvents::no_events()),
168 }
169 }
170}
171
172#[derive(Debug, Clone, Copy, PartialEq)]
174pub struct KeyState;
175
176#[derive(Debug, Clone, Copy, PartialEq)]
178pub struct System<
179 R,
180 Keys: Index<usize, Output = Key<R, MAX_TAP_DANCE_DEFINITIONS>>,
181 const MAX_TAP_DANCE_DEFINITIONS: usize,
182> {
183 keys: Keys,
184}
185
186impl<
187 R,
188 Keys: Index<usize, Output = Key<R, MAX_TAP_DANCE_DEFINITIONS>>,
189 const MAX_TAP_DANCE_DEFINITIONS: usize,
190 > System<R, Keys, MAX_TAP_DANCE_DEFINITIONS>
191{
192 pub const fn new(key_data: Keys) -> Self {
194 Self { keys: key_data }
195 }
196}
197
198impl<
199 R: Copy + Debug,
200 Keys: Debug + Index<usize, Output = Key<R, MAX_TAP_DANCE_DEFINITIONS>>,
201 const MAX_TAP_DANCE_DEFINITIONS: usize,
202 > key::System<R> for System<R, Keys, MAX_TAP_DANCE_DEFINITIONS>
203{
204 type Ref = Ref;
205 type Context = Context;
206 type Event = Event;
207 type PendingKeyState = PendingKeyState;
208 type KeyState = KeyState;
209
210 fn new_pressed_key(
211 &self,
212 keymap_index: u16,
213 context: &Self::Context,
214 _key_ref: Ref,
215 ) -> (
216 key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
217 key::KeyEvents<Self::Event>,
218 ) {
219 let td_pks = PendingKeyState::new();
220 let pk = key::PressedKeyResult::Pending(td_pks);
221
222 let timeout_ev = Event::NextPressTimeout(0);
223 let key_ev = key::Event::Key {
224 keymap_index,
225 key_event: timeout_ev,
226 };
227 let pke = key::KeyEvents::scheduled_event(key::ScheduledEvent::after(
228 context.config.timeout,
229 key_ev,
230 ));
231
232 (pk, pke)
233 }
234
235 fn update_pending_state(
236 &self,
237 pending_state: &mut Self::PendingKeyState,
238 keymap_index: u16,
239 context: &Self::Context,
240 Ref(key_index): Ref,
241 event: key::Event<Self::Event>,
242 ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
243 let key = &self.keys[key_index as usize];
244 let (maybe_resolution, pke) = pending_state.handle_event(context, keymap_index, event);
245
246 if let Some(TapDanceResolution(idx)) = maybe_resolution {
247 let new_key_ref = key.definitions[idx as usize].unwrap();
248
249 (
250 Some(key::NewPressedKey::key(new_key_ref)),
251 pke.into_events(),
252 )
253 } else {
254 let definition_count = key.definitions.iter().filter(|o| o.is_some()).count();
256 if pending_state.press_count as usize >= definition_count - 1 {
257 let idx = definition_count - 1;
258 let new_key_ref = key.definitions[idx].unwrap();
259
260 (
261 Some(key::NewPressedKey::key(new_key_ref)),
262 pke.into_events(),
263 )
264 } else {
265 (None, pke.into_events())
266 }
267 }
268 }
269
270 fn update_state(
271 &self,
272 _key_state: &mut Self::KeyState,
273 _ref: &Self::Ref,
274 _context: &Self::Context,
275 _keymap_index: u16,
276 _event: key::Event<Self::Event>,
277 ) -> key::KeyEvents<Self::Event> {
278 panic!() }
280
281 fn key_output(
282 &self,
283 _key_ref: &Self::Ref,
284 _key_state: &Self::KeyState,
285 ) -> Option<key::KeyOutput> {
286 panic!() }
288}
289
290#[cfg(test)]
291mod tests {
292 use super::*;
293
294 #[test]
295 fn test_sizeof_ref() {
296 assert_eq!(1, core::mem::size_of::<Ref>());
297 }
298
299 #[test]
300 fn test_sizeof_event() {
301 assert_eq!(1, core::mem::size_of::<Event>());
302 }
303}