smart_keymap/
key.rs

1use core::fmt::Debug;
2use core::marker::PhantomData;
3
4use serde::{Deserialize, Serialize};
5
6use crate::input;
7
8/// Keymap Callback keys
9pub mod callback;
10/// CapsWord key(s).
11pub mod caps_word;
12/// Chorded keys. (Chording functionality).
13pub mod chorded;
14/// Custom keys.
15pub mod custom;
16/// HID Keyboard keys.
17pub mod keyboard;
18/// Layered keys. (Layering functionality).
19pub mod layered;
20/// Sticky Modifier keys.
21pub mod sticky;
22/// Tap-Dance keys.
23pub mod tap_dance;
24/// Tap-Hold keys.
25pub mod tap_hold;
26
27/// "Composite" keys; an aggregate type used for a common context and event.
28pub mod composite;
29
30/// The maximum number of key events that are emitted [Key] or [KeyState].
31pub const MAX_KEY_EVENTS: usize = 4;
32
33/// The maximum length of a key path.
34pub const MAX_KEY_PATH_LEN: usize = 4;
35
36/// Sequence of indices into a key map.
37#[derive(Debug, Clone, PartialEq, Eq)]
38pub struct KeyPath(heapless::Vec<u16, MAX_KEY_PATH_LEN>);
39
40impl KeyPath {
41    /// Returns the keymap index (the first item in the path).
42    pub fn keymap_index(&self) -> u16 {
43        self.0[0]
44    }
45
46    /// Adds an item to the KeyPath.
47    pub fn append_path_item(&self, item: u16) -> KeyPath {
48        let mut kp = self.clone();
49        kp.0.push(item).unwrap();
50        kp
51    }
52}
53
54impl core::ops::Deref for KeyPath {
55    type Target = [u16];
56
57    fn deref(&self) -> &Self::Target {
58        &self.0
59    }
60}
61
62/// Events emitted when a [Key] is pressed.
63#[derive(Debug, PartialEq, Eq)]
64pub struct KeyEvents<E, const M: usize = { MAX_KEY_EVENTS }>(heapless::Vec<ScheduledEvent<E>, M>);
65
66impl<E: Copy + Debug> KeyEvents<E> {
67    /// Constructs a [KeyEvents] with no events scheduled.
68    pub fn no_events() -> Self {
69        KeyEvents(None.into_iter().collect())
70    }
71
72    /// Constructs a [KeyEvents] with an immediate [Event].
73    pub fn event(event: Event<E>) -> Self {
74        KeyEvents(Some(ScheduledEvent::immediate(event)).into_iter().collect())
75    }
76
77    /// Constructs a [KeyEvents] with an [Event] scheduled after a delay.
78    pub fn scheduled_event(sch_event: ScheduledEvent<E>) -> Self {
79        KeyEvents(Some(sch_event).into_iter().collect())
80    }
81
82    /// Adds an event with the schedule to the [KeyEvents].
83    pub fn schedule_event(&mut self, delay: u16, event: Event<E>) {
84        self.0.push(ScheduledEvent::after(delay, event)).unwrap();
85    }
86
87    /// Adds events from the other [KeyEvents] to the [KeyEvents].
88    pub fn extend(&mut self, other: KeyEvents<E>) {
89        other.0.into_iter().for_each(|ev| self.0.push(ev).unwrap());
90    }
91
92    /// Adds an event from to the [KeyEvents].
93    pub fn add_event(&mut self, ev: ScheduledEvent<E>) {
94        self.0.push(ev).unwrap();
95    }
96
97    /// Maps over the KeyEvents.
98    pub fn map_events<F>(&self, f: fn(E) -> F) -> KeyEvents<F> {
99        KeyEvents(
100            self.0
101                .as_slice()
102                .iter()
103                .map(|sch_ev| sch_ev.map_scheduled_event(f))
104                .collect(),
105        )
106    }
107
108    /// Maps the KeyEvents to a new type.
109    pub fn into_events<F>(&self) -> KeyEvents<F>
110    where
111        E: Into<F>,
112    {
113        KeyEvents(
114            self.0
115                .as_slice()
116                .iter()
117                .map(|sch_ev| sch_ev.map_scheduled_event(|ev| ev.into()))
118                .collect(),
119        )
120    }
121}
122
123impl<E: Debug, const M: usize> IntoIterator for KeyEvents<E, M> {
124    type Item = ScheduledEvent<E>;
125    type IntoIter = <heapless::Vec<ScheduledEvent<E>, M> as IntoIterator>::IntoIter;
126
127    fn into_iter(self) -> Self::IntoIter {
128        self.0.into_iter()
129    }
130}
131
132/// Newtype for invoking new_pressed_key on the key at the given [KeyPath].
133#[derive(Debug)]
134pub enum NewPressedKey {
135    /// Invoke new_pressed_key on the key at the given [KeyPath].
136    Key(KeyPath),
137    /// For keys which do nothing when pressed.
138    NoOp,
139}
140
141impl NewPressedKey {
142    /// Constructs a NewPressedKey value.
143    pub fn key_path(key_path: KeyPath) -> Self {
144        NewPressedKey::Key(key_path)
145    }
146
147    /// Constructs a NoOp NewPressedKey value.
148    pub fn no_op() -> Self {
149        NewPressedKey::NoOp
150    }
151}
152
153/// Pressed Key which may be pending, or a resolved key state.
154#[derive(Debug)]
155pub enum PressedKeyResult<PKS, KS> {
156    /// Unresolved key state. (e.g. tap-hold or chorded keys when first pressed).
157    Pending(KeyPath, PKS),
158    /// Resolved as a new pressed key.
159    NewPressedKey(NewPressedKey),
160    /// Resolved key state.
161    Resolved(KS),
162}
163
164/// Constructs key path with the given keymap index.
165pub fn key_path(keymap_index: u16) -> KeyPath {
166    let mut vec = heapless::Vec::new();
167    vec.push(keymap_index).unwrap();
168    KeyPath(vec)
169}
170
171impl<PKS, KS> PressedKeyResult<PKS, KS> {
172    /// Returns the Resolved variant, or else panics.
173    #[cfg(feature = "std")]
174    pub fn unwrap_resolved(self) -> KS {
175        match self {
176            PressedKeyResult::Resolved(r) => r,
177            _ => panic!("PressedKeyResult::unwrap_resolved: not Resolved"),
178        }
179    }
180
181    /// Adds an item to the KeyPath if the pressed key result is pending.
182    pub fn append_path_item(self, item: u16) -> Self {
183        match self {
184            PressedKeyResult::Pending(key_path, pks) => {
185                PressedKeyResult::Pending(key_path.append_path_item(item), pks)
186            }
187            pkr => pkr,
188        }
189    }
190}
191
192/// The interface for `Key` behaviour.
193///
194/// A `Key` has an associated [Context], `Event`, and [KeyState].
195///
196/// The generic `PK` is used as the type of the `PressedKey` that the `Key`
197///  produces.
198/// (e.g. [layered::LayeredKey]'s pressed key state passes-through to
199///  the keys of its layers).
200pub trait Key: Debug {
201    /// The associated [Context] is used to provide state that
202    ///  may affect behaviour when pressing the key.
203    /// (e.g. the behaviour of [layered::LayeredKey] depends on which
204    ///  layers are active in [layered::Context]).
205    type Context: Copy;
206
207    /// The associated `Event` is to be handled by the associated [Context],
208    ///  pending key states, and key states.
209    type Event: Copy + Debug + PartialEq;
210
211    /// Associated pending key state.
212    type PendingKeyState;
213
214    /// Associated key state type.
215    type KeyState;
216
217    /// [Key::new_pressed_key] produces a pressed key value, and may
218    ///  yield some [ScheduledEvent]s.
219    /// (e.g. [tap_hold::Key] schedules a [tap_hold::Event::TapHoldTimeout]
220    ///  so that holding the key resolves as a hold).
221    fn new_pressed_key(
222        &self,
223        context: &Self::Context,
224        key_path: KeyPath,
225    ) -> (
226        PressedKeyResult<Self::PendingKeyState, Self::KeyState>,
227        KeyEvents<Self::Event>,
228    );
229
230    /// Update the given pending key state with the given impl.
231    fn handle_event(
232        &self,
233        pending_state: &mut Self::PendingKeyState,
234        context: &Self::Context,
235        key_path: KeyPath,
236        event: Event<Self::Event>,
237    ) -> (Option<NewPressedKey>, KeyEvents<Self::Event>);
238
239    /// Return a reference to the key for the given path.
240    fn lookup(
241        &self,
242        path: &[u16],
243    ) -> &dyn Key<
244        Context = Self::Context,
245        Event = Self::Event,
246        PendingKeyState = Self::PendingKeyState,
247        KeyState = Self::KeyState,
248    >;
249}
250
251/// Used to provide state that may affect behaviour when pressing the key.
252///
253/// e.g. the behaviour of [layered::LayeredKey] depends on which
254///  layers are active in [layered::Context].
255pub trait Context: Clone + Copy {
256    /// The type of `Event` the context handles.
257    type Event;
258
259    /// Used to update the [Context]'s state.
260    fn handle_event(&mut self, event: Event<Self::Event>) -> KeyEvents<Self::Event>;
261}
262
263/// Bool flags for each of the modifier keys (left ctrl, etc.).
264#[derive(Deserialize, Serialize, Default, Clone, Copy, PartialEq, Eq)]
265pub struct KeyboardModifiers(u8);
266
267impl core::ops::Deref for KeyboardModifiers {
268    type Target = u8;
269
270    fn deref(&self) -> &Self::Target {
271        &self.0
272    }
273}
274
275impl core::fmt::Debug for KeyboardModifiers {
276    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
277        let mut ds = f.debug_struct("KeyboardModifiers");
278        if self.0 & Self::LEFT_CTRL_U8 != 0 {
279            ds.field("left_ctrl", &true);
280        }
281        if self.0 & Self::LEFT_SHIFT_U8 != 0 {
282            ds.field("left_shift", &true);
283        }
284        if self.0 & Self::LEFT_ALT_U8 != 0 {
285            ds.field("left_alt", &true);
286        }
287        if self.0 & Self::LEFT_GUI_U8 != 0 {
288            ds.field("left_gui", &true);
289        }
290        if self.0 & Self::RIGHT_CTRL_U8 != 0 {
291            ds.field("right_ctrl", &true);
292        }
293        if self.0 & Self::RIGHT_SHIFT_U8 != 0 {
294            ds.field("right_shift", &true);
295        }
296        if self.0 & Self::RIGHT_ALT_U8 != 0 {
297            ds.field("right_alt", &true);
298        }
299        if self.0 & Self::RIGHT_GUI_U8 != 0 {
300            ds.field("right_gui", &true);
301        }
302        ds.finish_non_exhaustive()
303    }
304}
305
306impl KeyboardModifiers {
307    /// Byte value for left ctrl.
308    pub const LEFT_CTRL_U8: u8 = 0x01;
309    /// Byte value for left shift.
310    pub const LEFT_SHIFT_U8: u8 = 0x02;
311    /// Byte value for left alt.
312    pub const LEFT_ALT_U8: u8 = 0x04;
313    /// Byte value for left gui.
314    pub const LEFT_GUI_U8: u8 = 0x08;
315    /// Byte value for right ctrl.
316    pub const RIGHT_CTRL_U8: u8 = 0x10;
317    /// Byte value for right shift.
318    pub const RIGHT_SHIFT_U8: u8 = 0x20;
319    /// Byte value for right alt.
320    pub const RIGHT_ALT_U8: u8 = 0x40;
321    /// Byte value for right gui.
322    pub const RIGHT_GUI_U8: u8 = 0x80;
323
324    /// Constructs with modifiers defaulting to false.
325    pub const fn new() -> Self {
326        KeyboardModifiers(0x00)
327    }
328
329    /// Constructs with modifiers with the given byte.
330    pub const fn from_byte(b: u8) -> Self {
331        KeyboardModifiers(b)
332    }
333
334    /// Constructs with the given key_code.
335    ///
336    /// Returns None if the key_code is not a modifier key code.
337    pub const fn from_key_code(key_code: u8) -> Option<Self> {
338        match key_code {
339            0xE0 => Some(Self::LEFT_CTRL),
340            0xE1 => Some(Self::LEFT_SHIFT),
341            0xE2 => Some(Self::LEFT_ALT),
342            0xE3 => Some(Self::LEFT_GUI),
343            0xE4 => Some(Self::RIGHT_CTRL),
344            0xE5 => Some(Self::RIGHT_SHIFT),
345            0xE6 => Some(Self::RIGHT_ALT),
346            0xE7 => Some(Self::RIGHT_GUI),
347            _ => None,
348        }
349    }
350
351    /// Const for no modifiers
352    pub const NONE: KeyboardModifiers = KeyboardModifiers {
353        ..KeyboardModifiers::new()
354    };
355
356    /// Const for left ctrl.
357    pub const LEFT_CTRL: KeyboardModifiers = KeyboardModifiers(Self::LEFT_CTRL_U8);
358
359    /// Const for left shift.
360    pub const LEFT_SHIFT: KeyboardModifiers = KeyboardModifiers(Self::LEFT_SHIFT_U8);
361
362    /// Const for left alt.
363    pub const LEFT_ALT: KeyboardModifiers = KeyboardModifiers(Self::LEFT_ALT_U8);
364
365    /// Const for left gui.
366    pub const LEFT_GUI: KeyboardModifiers = KeyboardModifiers(Self::LEFT_GUI_U8);
367
368    /// Const for right ctrl.
369    pub const RIGHT_CTRL: KeyboardModifiers = KeyboardModifiers(Self::RIGHT_CTRL_U8);
370
371    /// Const for right shift.
372    pub const RIGHT_SHIFT: KeyboardModifiers = KeyboardModifiers(Self::RIGHT_SHIFT_U8);
373
374    /// Const for right alt.
375    pub const RIGHT_ALT: KeyboardModifiers = KeyboardModifiers(Self::RIGHT_ALT_U8);
376
377    /// Const for right gui.
378    pub const RIGHT_GUI: KeyboardModifiers = KeyboardModifiers(Self::RIGHT_GUI_U8);
379
380    /// Predicate for whether the key code is a modifier key code.
381    pub const fn is_modifier_key_code(key_code: u8) -> bool {
382        matches!(key_code, 0xE0..=0xE7)
383    }
384
385    /// Constructs a Vec of key codes from the modifiers.
386    pub fn as_key_codes(&self) -> heapless::Vec<u8, 8> {
387        let mut key_codes = heapless::Vec::new();
388
389        if self.0 & Self::LEFT_CTRL_U8 != 0 {
390            key_codes.push(0xE0).unwrap();
391        }
392        if self.0 & Self::LEFT_SHIFT_U8 != 0 {
393            key_codes.push(0xE1).unwrap();
394        }
395        if self.0 & Self::LEFT_ALT_U8 != 0 {
396            key_codes.push(0xE2).unwrap();
397        }
398        if self.0 & Self::LEFT_GUI_U8 != 0 {
399            key_codes.push(0xE3).unwrap();
400        }
401        if self.0 & Self::RIGHT_CTRL_U8 != 0 {
402            key_codes.push(0xE4).unwrap();
403        }
404        if self.0 & Self::RIGHT_SHIFT_U8 != 0 {
405            key_codes.push(0xE5).unwrap();
406        }
407        if self.0 & Self::RIGHT_ALT_U8 != 0 {
408            key_codes.push(0xE6).unwrap();
409        }
410        if self.0 & Self::RIGHT_GUI_U8 != 0 {
411            key_codes.push(0xE7).unwrap();
412        }
413
414        key_codes
415    }
416
417    /// Constructs the byte for the modifiers of an HID keyboard report.
418    pub fn as_byte(&self) -> u8 {
419        self.as_key_codes()
420            .iter()
421            .fold(0u8, |acc, &kc| acc | (1 << (kc - 0xE0)))
422    }
423
424    /// Union of two KeyboardModifiers, taking "or" of each modifier.
425    pub const fn union(&self, other: &KeyboardModifiers) -> KeyboardModifiers {
426        KeyboardModifiers(self.0 | other.0)
427    }
428
429    /// Whether this keyboard modifiers includes all the other modifiers.
430    pub const fn has_modifiers(&self, other: &KeyboardModifiers) -> bool {
431        self.0 & other.0 != 0
432    }
433}
434
435/// Enum for the different types of key codes.
436#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)]
437pub enum KeyUsage {
438    /// Key usage code.
439    Keyboard(u8),
440    /// Custom code. (Behaviour defined by firmware implementation).
441    Custom(u8),
442}
443
444/// Struct for the output from [KeyState].
445#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)]
446pub struct KeyOutput {
447    key_code: KeyUsage,
448    key_modifiers: KeyboardModifiers,
449}
450
451impl KeyOutput {
452    /// Constructs a [KeyOutput] from a key code.
453    pub fn from_key_code(key_code: u8) -> Self {
454        if let Some(key_modifiers) = KeyboardModifiers::from_key_code(key_code) {
455            KeyOutput {
456                key_code: KeyUsage::Keyboard(0x00),
457                key_modifiers,
458            }
459        } else {
460            KeyOutput {
461                key_code: KeyUsage::Keyboard(key_code),
462                key_modifiers: KeyboardModifiers::new(),
463            }
464        }
465    }
466
467    /// Constructs a [KeyOutput] from a key code with the given keyboard modifiers.
468    pub fn from_key_code_with_modifiers(key_code: u8, key_modifiers: KeyboardModifiers) -> Self {
469        let KeyOutput {
470            key_code,
471            key_modifiers: km,
472        } = Self::from_key_code(key_code);
473        KeyOutput {
474            key_code,
475            key_modifiers: km.union(&key_modifiers),
476        }
477    }
478
479    /// Constructs a [KeyOutput] for just the given keyboard modifiers.
480    pub fn from_key_modifiers(key_modifiers: KeyboardModifiers) -> Self {
481        KeyOutput {
482            key_code: KeyUsage::Keyboard(0x00),
483            key_modifiers,
484        }
485    }
486
487    /// Constructs a [KeyOutput] from a custom code.
488    pub fn from_custom_code(custom_code: u8) -> Self {
489        KeyOutput {
490            key_code: KeyUsage::Custom(custom_code),
491            key_modifiers: KeyboardModifiers::new(),
492        }
493    }
494
495    /// Returns the key code value.
496    pub fn key_code(&self) -> KeyUsage {
497        self.key_code
498    }
499
500    /// Returns the keyboard modifiers of the key output.
501    pub fn key_modifiers(&self) -> KeyboardModifiers {
502        self.key_modifiers
503    }
504}
505
506/// Implements functionality for the pressed key.
507pub trait KeyState: Debug {
508    /// The type of `Context` the pressed key state handles.
509    type Context;
510    /// The type of `Event` the pressed key state handles.
511    type Event: Copy + Debug;
512
513    /// Used to update the [KeyState]'s state, and possibly yield event(s).
514    fn handle_event(
515        &mut self,
516        _context: &Self::Context,
517        _keymap_index: u16,
518        _event: Event<Self::Event>,
519    ) -> KeyEvents<Self::Event> {
520        KeyEvents::no_events()
521    }
522
523    /// Output for the pressed key state.
524    fn key_output(&self) -> Option<KeyOutput> {
525        None
526    }
527}
528
529/// A NoOp key state, for keys which do nothing when pressed.
530#[derive(Debug, Clone, Copy, PartialEq, Eq)]
531pub struct NoOpKeyState<Ctx, Ev>(PhantomData<(Ctx, Ev)>);
532
533impl<Ctx, Ev> NoOpKeyState<Ctx, Ev> {
534    /// Constructs a NoOpKeyState value.
535    pub const fn new() -> Self {
536        NoOpKeyState(PhantomData)
537    }
538}
539
540impl<Ctx: Debug, Ev: Copy + Debug> KeyState for NoOpKeyState<Ctx, Ev> {
541    type Context = Ctx;
542    type Event = Ev;
543}
544
545impl<Ctx, Ev> Default for NoOpKeyState<Ctx, Ev> {
546    fn default() -> Self {
547        Self::new()
548    }
549}
550
551/// Errors for [TryFrom] implementations.
552#[allow(unused)]
553pub enum EventError {
554    /// Error when mapping isn't possible.
555    ///
556    /// e.g. trying to map variants of [composite::Event] to [tap_hold::Event].
557    UnmappableEvent,
558}
559
560/// Convenience alias for a [Result] with an [EventError].
561type EventResult<T> = Result<T, EventError>;
562
563/// Events which are either input, or for a particular [Key::Event].
564///
565/// It's useful for [Key] implementations to use [Event] with [Key::Event],
566///  and map [Key::Event] to and partially from [composite::Event].
567#[derive(Debug, Clone, Copy, PartialEq, Eq)]
568pub enum Event<T> {
569    /// Keymap input events, such as physical key presses.
570    Input(input::Event),
571    /// [Key] implementation specific events.
572    Key {
573        /// The keymap index the event was generated from.
574        keymap_index: u16,
575        /// A [Key::Event] event.
576        key_event: T,
577    },
578    /// Invoke a keymap callback
579    Keymap(crate::keymap::KeymapEvent),
580}
581
582impl<T: Copy> Event<T> {
583    /// Constructs an [Event] from an [Key::Event].
584    pub fn key_event(keymap_index: u16, key_event: T) -> Self {
585        Event::Key {
586            keymap_index,
587            key_event,
588        }
589    }
590
591    /// Maps the Event into a new type.
592    pub fn map_key_event<U>(self, f: fn(T) -> U) -> Event<U> {
593        match self {
594            Event::Input(event) => Event::Input(event),
595            Event::Key {
596                key_event,
597                keymap_index,
598            } => Event::Key {
599                key_event: f(key_event),
600                keymap_index,
601            },
602            Event::Keymap(cb) => Event::Keymap(cb),
603        }
604    }
605
606    /// Maps the Event into a new type.
607    pub fn into_key_event<U>(self) -> Event<U>
608    where
609        T: Into<U>,
610    {
611        self.map_key_event(|ke| ke.into())
612    }
613
614    /// Maps the Event into a new type.
615    pub fn try_into_key_event<U, E>(self, f: fn(T) -> Result<U, E>) -> EventResult<Event<U>> {
616        match self {
617            Event::Input(event) => Ok(Event::Input(event)),
618            Event::Key {
619                key_event,
620                keymap_index,
621            } => f(key_event)
622                .map(|key_event| Event::Key {
623                    key_event,
624                    keymap_index,
625                })
626                .map_err(|_| EventError::UnmappableEvent),
627            Event::Keymap(cb) => Ok(Event::Keymap(cb)),
628        }
629    }
630}
631
632impl<T> From<input::Event> for Event<T> {
633    fn from(event: input::Event) -> Self {
634        Event::Input(event)
635    }
636}
637
638/// Schedule for a [ScheduledEvent].
639#[allow(unused)]
640#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
641pub enum Schedule {
642    /// Immediately.
643    Immediate,
644    /// After a given number of `tick`s.
645    After(u16),
646}
647
648/// Schedules a given `T` with [Event], for some [Schedule].
649#[derive(Debug, Clone, Copy, PartialEq, Eq)]
650pub struct ScheduledEvent<T> {
651    /// Whether to handle the event immediately, or after some delay.
652    pub schedule: Schedule,
653    /// The event.
654    pub event: Event<T>,
655}
656
657impl<T: Copy> ScheduledEvent<T> {
658    /// Constructs a [ScheduledEvent] with [Schedule::Immediate].
659    #[allow(unused)]
660    pub fn immediate(event: Event<T>) -> Self {
661        ScheduledEvent {
662            schedule: Schedule::Immediate,
663            event,
664        }
665    }
666
667    /// Constructs a [ScheduledEvent] with [Schedule::After].
668    pub fn after(delay: u16, event: Event<T>) -> Self {
669        ScheduledEvent {
670            schedule: Schedule::After(delay),
671            event,
672        }
673    }
674
675    /// Maps the Event of the ScheduledEvent into a new type.
676    pub fn map_scheduled_event<U>(self, f: fn(T) -> U) -> ScheduledEvent<U> {
677        ScheduledEvent {
678            event: self.event.map_key_event(f),
679            schedule: self.schedule,
680        }
681    }
682
683    /// Maps the ScheduledEvent into a new type.
684    pub fn into_scheduled_event<U>(self) -> ScheduledEvent<U>
685    where
686        T: Into<U>,
687    {
688        self.map_scheduled_event(|e| e.into())
689    }
690}