Skip to main content

smart_keymap_core/key/
keyboard.rs

1use core::fmt::Debug;
2use core::marker::PhantomData;
3use core::ops::Index;
4
5use serde::Deserialize;
6
7use crate::key;
8
9/// Reference for a keyboard key.
10#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
11pub enum Ref {
12    /// A key code without modifiers. (Value is the HID usage code).
13    KeyCode(u8),
14    /// A modifiers. (Value is a bitfield of `key::KeyboardModifiers`).
15    Modifiers(u8),
16    /// A key code with modifiers. (Value is the index into the key data array of [System]).
17    KeyCodeAndModifier(u8),
18}
19
20/// A key for HID Keyboard usage codes.
21#[derive(Deserialize, Clone, Copy, PartialEq, Default)]
22pub struct Key {
23    /// HID usage code.
24    #[serde(default)]
25    pub key_code: u8,
26    /// Modifiers.
27    #[serde(default)]
28    pub modifiers: key::KeyboardModifiers,
29}
30
31impl core::fmt::Debug for Key {
32    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33        match (
34            self.key_code != 0x00,
35            self.modifiers != key::KeyboardModifiers::new(),
36        ) {
37            (true, true) => f
38                .debug_struct("Key")
39                .field("key_code", &self.key_code)
40                .field("modifiers", &self.modifiers)
41                .finish(),
42            (false, true) => f
43                .debug_struct("Key")
44                .field("modifiers", &self.modifiers)
45                .finish(),
46            _ => f
47                .debug_struct("Key")
48                .field("key_code", &self.key_code)
49                .finish(),
50        }
51    }
52}
53
54/// Context for keyboard keys. (No context).
55#[derive(Debug, Clone, Copy, PartialEq)]
56pub struct Context;
57
58impl Context {
59    /// No runtime state to clear.
60    pub fn reset(&mut self) {}
61}
62
63impl key::Context for Context {
64    type Event = Event;
65
66    /// Used to update the [Context]'s state.
67    fn handle_event(&mut self, _event: key::Event<Self::Event>) -> key::KeyEvents<Self::Event> {
68        key::KeyEvents::no_events()
69    }
70
71    fn reset(&mut self) {
72        Context::reset(self);
73    }
74}
75
76// We want key::keyboard::Context to impl SetKeymapContext, because it's plausible
77// that some keyboard implementations only use key::keyboard keys,
78// and SetKeymapContext is required for keymap::Keymap.
79impl crate::keymap::SetKeymapContext for Context {
80    fn set_keymap_context(&mut self, _context: crate::keymap::KeymapContext) {}
81}
82
83/// The event type for keyboard keys. (No events).
84#[derive(Debug, Clone, Copy, PartialEq)]
85pub struct Event;
86
87/// The pending key state type for keyboard keys. (No pending state).
88#[derive(Debug, Clone, Copy, PartialEq)]
89pub struct PendingKeyState;
90
91/// Key state used by [System].
92#[derive(Debug, Clone, Copy, PartialEq)]
93pub struct KeyState;
94
95/// The [key::System] implementation for keyboard keys.
96#[derive(Debug, Clone, Copy, PartialEq)]
97pub struct System<R: Debug, Keys: Index<usize, Output = Key>> {
98    keys: Keys,
99    marker: PhantomData<R>,
100}
101
102impl<R: Debug, Keys: Index<usize, Output = Key>> System<R, Keys> {
103    /// Constructs a new [System] with the given key data.
104    ///
105    /// The key data is for keys with both key codes and modifiers.
106    pub const fn new(keys: Keys) -> Self {
107        Self {
108            keys,
109            marker: PhantomData,
110        }
111    }
112}
113
114impl<R: Debug, Keys: Debug + Index<usize, Output = Key>> key::System<R> for System<R, Keys> {
115    type Ref = Ref;
116    type Context = Context;
117    type Event = Event;
118    type PendingKeyState = PendingKeyState;
119    type KeyState = KeyState;
120
121    fn new_pressed_key(
122        &self,
123        _keymap_index: u16,
124        _context: &Self::Context,
125        _key_ref: Ref,
126    ) -> (
127        key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
128        key::KeyEvents<Self::Event>,
129    ) {
130        (
131            key::PressedKeyResult::Resolved(KeyState),
132            key::KeyEvents::no_events(),
133        )
134    }
135
136    fn update_pending_state(
137        &self,
138        _pending_state: &mut Self::PendingKeyState,
139        _keymap_index: u16,
140        _context: &Self::Context,
141        _key_ref: Ref,
142        _event: key::Event<Self::Event>,
143    ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
144        panic!()
145    }
146
147    fn update_state(
148        &self,
149        _key_state: &mut Self::KeyState,
150        _ref: &Self::Ref,
151        _context: &Self::Context,
152        _keymap_index: u16,
153        _event: key::Event<Self::Event>,
154    ) -> key::KeyEvents<Self::Event> {
155        key::KeyEvents::no_events()
156    }
157
158    fn key_output(
159        &self,
160        key_ref: &Self::Ref,
161        _key_state: &Self::KeyState,
162    ) -> Option<key::KeyOutput> {
163        match key_ref {
164            Ref::KeyCode(kc) => Some(key::KeyOutput::from_key_code(*kc)),
165            Ref::Modifiers(m) => Some(key::KeyOutput::from_key_modifiers(
166                key::KeyboardModifiers::from_byte(*m),
167            )),
168            Ref::KeyCodeAndModifier(idx) => {
169                let Key {
170                    key_code,
171                    modifiers,
172                } = self.keys[*idx as usize];
173                Some(key::KeyOutput::from_key_code_with_modifiers(
174                    key_code, modifiers,
175                ))
176            }
177        }
178    }
179}
180
181#[cfg(test)]
182mod tests {
183    use super::*;
184
185    #[test]
186    fn test_sizeof_ref() {
187        assert_eq!(2, core::mem::size_of::<Ref>());
188    }
189
190    #[test]
191    fn test_sizeof_event() {
192        assert_eq!(0, core::mem::size_of::<Event>());
193    }
194}