1use core::fmt::Debug;
14use core::marker::PhantomData;
15use core::ops::Index;
16
17use serde::Deserialize;
18
19use crate::key;
20use crate::keymap;
21
22#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
24pub struct Ref(pub Key);
25
26#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
28pub enum Key {
29 Repeat,
31 AltRepeat,
35 Adaptive(u8),
41}
42
43impl Key {
44 pub const fn new_repeat() -> Self {
46 Key::Repeat
47 }
48
49 pub const fn new_alt_repeat() -> Self {
51 Key::AltRepeat
52 }
53
54 pub const fn new_adaptive(index: u8) -> Self {
56 Key::Adaptive(index)
57 }
58}
59
60pub const MAX_ADAPTIVE_RULES: usize = 8;
64
65#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
68pub struct AltRepeatRule {
69 pub prev: key::KeyOutput,
71 pub emit: key::KeyOutput,
73}
74
75impl AltRepeatRule {
76 pub const EMPTY: Self = Self {
78 prev: key::KeyOutput::NO_OUTPUT,
79 emit: key::KeyOutput::NO_OUTPUT,
80 };
81
82 pub const fn new(prev: key::KeyOutput, emit: key::KeyOutput) -> Self {
84 Self { prev, emit }
85 }
86}
87
88#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
92pub struct AdaptiveKey {
93 pub default: key::KeyOutput,
95 #[serde(deserialize_with = "deserialize_adaptive_rules")]
97 pub rules: [AltRepeatRule; MAX_ADAPTIVE_RULES],
98}
99
100impl AdaptiveKey {
101 pub const EMPTY: Self = Self {
103 default: key::KeyOutput::NO_OUTPUT,
104 rules: [AltRepeatRule::EMPTY; MAX_ADAPTIVE_RULES],
105 };
106
107 pub const fn new(default: key::KeyOutput, rules: [AltRepeatRule; MAX_ADAPTIVE_RULES]) -> Self {
109 Self { default, rules }
110 }
111
112 pub fn lookup(&self, prev: &key::KeyOutput) -> Option<key::KeyOutput> {
114 self.rules
115 .iter()
116 .find(|r| r.prev == *prev && **r != AltRepeatRule::EMPTY)
117 .map(|r| r.emit)
118 }
119}
120
121pub const fn adaptive_rules<const N: usize>(
123 rules: [AltRepeatRule; N],
124) -> [AltRepeatRule; MAX_ADAPTIVE_RULES] {
125 let mut out: [AltRepeatRule; MAX_ADAPTIVE_RULES] = [AltRepeatRule::EMPTY; MAX_ADAPTIVE_RULES];
126
127 if N > MAX_ADAPTIVE_RULES {
128 panic!("Too many adaptive rules for AdaptiveKey");
129 }
130
131 let mut i = 0;
132 while i < N {
133 out[i] = rules[i];
134 i += 1;
135 }
136 out
137}
138
139fn deserialize_adaptive_rules<'de, D>(
140 deserializer: D,
141) -> Result<[AltRepeatRule; MAX_ADAPTIVE_RULES], D::Error>
142where
143 D: serde::Deserializer<'de>,
144{
145 let rules_vec: heapless::Vec<AltRepeatRule, MAX_ADAPTIVE_RULES> =
146 Deserialize::deserialize(deserializer)?;
147
148 let mut rules_array: [AltRepeatRule; MAX_ADAPTIVE_RULES] =
149 [AltRepeatRule::EMPTY; MAX_ADAPTIVE_RULES];
150 for (i, rule) in rules_vec.iter().enumerate() {
151 rules_array[i] = *rule;
152 }
153
154 Ok(rules_array)
155}
156
157fn output_or_none(output: key::KeyOutput) -> Option<key::KeyOutput> {
158 if is_rememberable(&output) {
159 Some(output)
160 } else {
161 None
162 }
163}
164
165#[derive(Deserialize, Clone, Copy, PartialEq)]
167pub struct Config<const ALT_REPEAT_RULE_COUNT: usize> {
168 #[serde(deserialize_with = "deserialize_alt_repeat")]
170 pub alt_repeat: [AltRepeatRule; ALT_REPEAT_RULE_COUNT],
171}
172
173struct AltRepeatDebugHelper<'a, const N: usize> {
174 rules: &'a [AltRepeatRule; N],
175}
176
177impl<'a, const N: usize> core::fmt::Debug for AltRepeatDebugHelper<'a, N> {
178 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
179 let last_non_empty = self
180 .rules
181 .iter()
182 .rposition(|r| *r != AltRepeatRule::EMPTY)
183 .map_or(0, |pos| pos + 1);
184 if last_non_empty < N {
185 f.debug_list()
186 .entries(&self.rules[..last_non_empty])
187 .finish_non_exhaustive()
188 } else {
189 f.debug_list().entries(&self.rules[..]).finish()
190 }
191 }
192}
193
194impl<const ALT_REPEAT_RULE_COUNT: usize> core::fmt::Debug for Config<ALT_REPEAT_RULE_COUNT> {
195 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
196 f.debug_struct("Config")
197 .field(
198 "alt_repeat",
199 &AltRepeatDebugHelper {
200 rules: &self.alt_repeat,
201 },
202 )
203 .finish()
204 }
205}
206
207pub const fn alt_repeat_rules<const N: usize, const ALT_REPEAT_RULE_COUNT: usize>(
209 rules: [AltRepeatRule; N],
210) -> [AltRepeatRule; ALT_REPEAT_RULE_COUNT] {
211 let mut out: [AltRepeatRule; ALT_REPEAT_RULE_COUNT] =
212 [AltRepeatRule::EMPTY; ALT_REPEAT_RULE_COUNT];
213
214 if N > ALT_REPEAT_RULE_COUNT {
215 panic!("Too many alt-repeat rules for alt_repeat array");
216 }
217
218 let mut i = 0;
219 while i < N {
220 out[i] = rules[i];
221 i += 1;
222 }
223 out
224}
225
226fn deserialize_alt_repeat<'de, D, const ALT_REPEAT_RULE_COUNT: usize>(
227 deserializer: D,
228) -> Result<[AltRepeatRule; ALT_REPEAT_RULE_COUNT], D::Error>
229where
230 D: serde::Deserializer<'de>,
231{
232 let rules_vec: heapless::Vec<AltRepeatRule, ALT_REPEAT_RULE_COUNT> =
233 Deserialize::deserialize(deserializer)?;
234
235 let mut rules_array: [AltRepeatRule; ALT_REPEAT_RULE_COUNT] =
236 [AltRepeatRule::EMPTY; ALT_REPEAT_RULE_COUNT];
237 for (i, rule) in rules_vec.iter().enumerate() {
238 rules_array[i] = *rule;
239 }
240
241 Ok(rules_array)
242}
243
244impl<const ALT_REPEAT_RULE_COUNT: usize> Config<ALT_REPEAT_RULE_COUNT> {
245 pub const fn new() -> Self {
247 Self {
248 alt_repeat: [AltRepeatRule::EMPTY; ALT_REPEAT_RULE_COUNT],
249 }
250 }
251
252 pub fn lookup_alt(&self, prev: &key::KeyOutput) -> Option<key::KeyOutput> {
254 self.alt_repeat
255 .iter()
256 .find(|r| r.prev == *prev && **r != AltRepeatRule::EMPTY)
257 .map(|r| r.emit)
258 }
259}
260
261impl<const ALT_REPEAT_RULE_COUNT: usize> Default for Config<ALT_REPEAT_RULE_COUNT> {
262 fn default() -> Self {
263 Self::new()
264 }
265}
266
267pub fn is_rememberable(key_output: &key::KeyOutput) -> bool {
272 *key_output != key::KeyOutput::NO_OUTPUT
273}
274
275#[derive(Debug, Clone, Copy, PartialEq)]
277pub struct Context<const ALT_REPEAT_RULE_COUNT: usize = 0> {
278 pub config: Config<ALT_REPEAT_RULE_COUNT>,
280 last: Option<key::KeyOutput>,
281}
282
283impl<const ALT_REPEAT_RULE_COUNT: usize> Default for Context<ALT_REPEAT_RULE_COUNT> {
284 fn default() -> Self {
285 Self::new()
286 }
287}
288
289impl<const ALT_REPEAT_RULE_COUNT: usize> Context<ALT_REPEAT_RULE_COUNT> {
290 pub const fn new() -> Self {
292 Self::from_config(Config::new())
293 }
294
295 pub const fn from_config(config: Config<ALT_REPEAT_RULE_COUNT>) -> Self {
297 Context { config, last: None }
298 }
299
300 pub fn reset(&mut self) {
302 *self = Self::from_config(self.config);
303 }
304
305 pub fn last(&self) -> Option<key::KeyOutput> {
307 self.last
308 }
309
310 fn handle_event(&mut self, event: key::Event<Event>) -> key::KeyEvents<Event> {
311 if let key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput { key_output, .. }) = event
312 {
313 if is_rememberable(&key_output) {
314 self.last = Some(key_output);
315 }
316 }
317 key::KeyEvents::no_events()
318 }
319}
320
321impl<const ALT_REPEAT_RULE_COUNT: usize> key::Context for Context<ALT_REPEAT_RULE_COUNT> {
322 type Event = Event;
323
324 fn handle_event(&mut self, event: key::Event<Self::Event>) -> key::KeyEvents<Self::Event> {
325 self.handle_event(event)
326 }
327
328 fn reset(&mut self) {
329 Context::reset(self);
330 }
331}
332
333#[derive(Debug, Clone, Copy, PartialEq)]
335pub struct Event;
336
337#[derive(Debug, Clone, Copy, PartialEq)]
339pub struct PendingKeyState;
340
341#[derive(Debug, Clone, Copy, PartialEq)]
343pub struct KeyState {
344 output: Option<key::KeyOutput>,
345}
346
347impl KeyState {
348 pub const fn new(output: Option<key::KeyOutput>) -> Self {
350 Self { output }
351 }
352
353 pub const fn output(&self) -> Option<key::KeyOutput> {
355 self.output
356 }
357}
358
359#[derive(Debug, Clone, Copy, PartialEq)]
361pub struct System<R, Keys = [AdaptiveKey; 0], const ALT_REPEAT_RULE_COUNT: usize = 0> {
362 keys: Keys,
363 _r: PhantomData<R>,
364}
365
366impl<R, Keys, const ALT_REPEAT_RULE_COUNT: usize> System<R, Keys, ALT_REPEAT_RULE_COUNT> {
367 pub const fn new(keys: Keys) -> Self {
369 Self {
370 keys,
371 _r: PhantomData,
372 }
373 }
374}
375
376impl<R, Keys: Default, const ALT_REPEAT_RULE_COUNT: usize> Default
377 for System<R, Keys, ALT_REPEAT_RULE_COUNT>
378{
379 fn default() -> Self {
380 Self::new(Keys::default())
381 }
382}
383
384impl<
385 R: Debug,
386 Keys: Debug + Index<usize, Output = AdaptiveKey>,
387 const ALT_REPEAT_RULE_COUNT: usize,
388 > key::System<R> for System<R, Keys, ALT_REPEAT_RULE_COUNT>
389{
390 type Ref = Ref;
391 type Context = Context<ALT_REPEAT_RULE_COUNT>;
392 type Event = Event;
393 type PendingKeyState = PendingKeyState;
394 type KeyState = KeyState;
395
396 fn new_pressed_key(
397 &self,
398 _keymap_index: u16,
399 context: &Self::Context,
400 Ref(key): Ref,
401 ) -> (
402 key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
403 key::KeyEvents<Self::Event>,
404 ) {
405 let output = match key {
406 Key::Repeat => context.last(),
407 Key::AltRepeat => context
408 .last()
409 .and_then(|last| context.config.lookup_alt(&last)),
410 Key::Adaptive(index) => {
411 let spec = &self.keys[index as usize];
412 let raw = context
413 .last()
414 .and_then(|last| spec.lookup(&last))
415 .unwrap_or(spec.default);
416 output_or_none(raw)
417 }
418 };
419 (
420 key::PressedKeyResult::Resolved(KeyState::new(output)),
421 key::KeyEvents::no_events(),
422 )
423 }
424
425 fn update_pending_state(
426 &self,
427 _pending_state: &mut Self::PendingKeyState,
428 _keymap_index: u16,
429 _context: &Self::Context,
430 _key_ref: Ref,
431 _event: key::Event<Self::Event>,
432 ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
433 panic!()
434 }
435
436 fn key_output(
437 &self,
438 _key_ref: &Self::Ref,
439 key_state: &Self::KeyState,
440 ) -> Option<key::KeyOutput> {
441 key_state.output()
442 }
443}
444
445#[cfg(test)]
446mod tests {
447 use super::*;
448 use crate::key::System as _;
449
450 #[test]
451 fn test_sizeof_ref() {
452 assert_eq!(2, core::mem::size_of::<Ref>());
454 }
455
456 #[test]
457 fn test_sizeof_event() {
458 assert_eq!(0, core::mem::size_of::<Event>());
459 }
460
461 #[test]
462 fn context_remembers_resolved_keyboard_output() {
463 let mut ctx = Context::<0>::new();
464 assert_eq!(None, ctx.last());
465
466 let key_output = key::KeyOutput::from_key_code(0x04);
467 let _ = key::Context::handle_event(
468 &mut ctx,
469 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput {
470 keymap_index: 0,
471 key_output,
472 }),
473 );
474
475 assert_eq!(Some(key_output), ctx.last());
476 }
477
478 #[test]
479 fn context_ignores_empty_output() {
480 let mut ctx = Context::<0>::new();
481 let remembered = key::KeyOutput::from_key_code(0x04);
482 ctx.last = Some(remembered);
483
484 let _ = key::Context::handle_event(
485 &mut ctx,
486 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput {
487 keymap_index: 0,
488 key_output: key::KeyOutput::NO_OUTPUT,
489 }),
490 );
491
492 assert_eq!(Some(remembered), ctx.last());
493 }
494
495 #[test]
496 fn repeat_pressed_key_uses_context_last() {
497 let system = System::<()>::new([]);
498 let mut ctx = Context::<0>::new();
499 let key_output = key::KeyOutput::from_key_code(0x05);
500 ctx.last = Some(key_output);
501
502 let (pkr, _) = system.new_pressed_key(0, &ctx, Ref(Key::Repeat));
503 let ks = pkr.unwrap_resolved();
504 assert_eq!(Some(key_output), system.key_output(&Ref(Key::Repeat), &ks));
505 }
506
507 #[test]
508 fn alt_repeat_looks_up_config_rule() {
509 let left = key::KeyOutput::from_key_code(0x50);
510 let right = key::KeyOutput::from_key_code(0x4F);
511 let config = Config {
512 alt_repeat: [AltRepeatRule::new(left, right)],
513 };
514 let mut ctx = Context::from_config(config);
515 ctx.last = Some(left);
516
517 let system = System::<(), [AdaptiveKey; 0], 1>::new([]);
518 let (pkr, _) = system.new_pressed_key(0, &ctx, Ref(Key::AltRepeat));
519 let ks = pkr.unwrap_resolved();
520 assert_eq!(Some(right), system.key_output(&Ref(Key::AltRepeat), &ks));
521 }
522
523 #[test]
524 fn alt_repeat_unmapped_is_none() {
525 let system = System::<()>::new([]);
526 let mut ctx = Context::<0>::new();
527 ctx.last = Some(key::KeyOutput::from_key_code(0x04));
528
529 let (pkr, _) = system.new_pressed_key(0, &ctx, Ref(Key::AltRepeat));
530 let ks = pkr.unwrap_resolved();
531 assert_eq!(None, system.key_output(&Ref(Key::AltRepeat), &ks));
532 }
533
534 #[test]
535 fn adaptive_uses_matching_rule() {
536 let a = key::KeyOutput::from_key_code(0x04);
538 let h = key::KeyOutput::from_key_code(0x0B);
539 let u = key::KeyOutput::from_key_code(0x18);
540 let keys = [AdaptiveKey::new(
541 h,
542 adaptive_rules([AltRepeatRule::new(a, u)]),
543 )];
544 let system = System::<(), _>::new(keys);
545 let mut ctx = Context::<0>::new();
546 ctx.last = Some(a);
547
548 let (pkr, _) = system.new_pressed_key(0, &ctx, Ref(Key::Adaptive(0)));
550 let ks = pkr.unwrap_resolved();
551
552 assert_eq!(Some(u), system.key_output(&Ref(Key::Adaptive(0)), &ks));
554 }
555
556 #[test]
557 fn adaptive_falls_back_to_default() {
558 let a = key::KeyOutput::from_key_code(0x04);
560 let b = key::KeyOutput::from_key_code(0x05);
561 let h = key::KeyOutput::from_key_code(0x0B);
562 let u = key::KeyOutput::from_key_code(0x18);
563 let keys = [AdaptiveKey::new(
564 h,
565 adaptive_rules([AltRepeatRule::new(a, u)]),
566 )];
567 let system = System::<(), _>::new(keys);
568 let mut ctx = Context::<0>::new();
569 ctx.last = Some(b);
570
571 let (pkr, _) = system.new_pressed_key(0, &ctx, Ref(Key::Adaptive(0)));
573 let ks = pkr.unwrap_resolved();
574
575 assert_eq!(Some(h), system.key_output(&Ref(Key::Adaptive(0)), &ks));
577 }
578
579 #[test]
580 fn adaptive_empty_history_uses_default() {
581 let h = key::KeyOutput::from_key_code(0x0B);
583 let keys = [AdaptiveKey::new(h, adaptive_rules([]))];
584 let system = System::<(), _>::new(keys);
585 let ctx = Context::<0>::new();
586
587 let (pkr, _) = system.new_pressed_key(0, &ctx, Ref(Key::Adaptive(0)));
589 let ks = pkr.unwrap_resolved();
590
591 assert_eq!(Some(h), system.key_output(&Ref(Key::Adaptive(0)), &ks));
593 }
594
595 #[test]
596 fn adaptive_noop_default_is_none() {
597 let system = System::<(), _>::new([AdaptiveKey::EMPTY]);
599 let ctx = Context::<0>::new();
600
601 let (pkr, _) = system.new_pressed_key(0, &ctx, Ref(Key::Adaptive(0)));
603 let ks = pkr.unwrap_resolved();
604
605 assert_eq!(None, system.key_output(&Ref(Key::Adaptive(0)), &ks));
607 }
608}