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