smart_keymap/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 key::Context for Context {
59    type Event = Event;
60
61    /// Used to update the [Context]'s state.
62    fn handle_event(&mut self, _event: key::Event<Self::Event>) -> key::KeyEvents<Self::Event> {
63        key::KeyEvents::no_events()
64    }
65}
66
67// We want key::keyboard::Context to impl SetKeymapContext, because it's plausible
68// that some keyboard implementations only use key::keyboard keys,
69// and SetKeymapContext is required for keymap::Keymap.
70impl crate::keymap::SetKeymapContext for Context {
71    fn set_keymap_context(&mut self, _context: crate::keymap::KeymapContext) {}
72}
73
74/// The event type for keyboard keys. (No events).
75#[derive(Debug, Clone, Copy, PartialEq)]
76pub struct Event;
77
78/// The pending key state type for keyboard keys. (No pending state).
79#[derive(Debug, Clone, Copy, PartialEq)]
80pub struct PendingKeyState;
81
82/// Key state used by [System].
83#[derive(Debug, Clone, Copy, PartialEq)]
84pub struct KeyState;
85
86/// The [key::System] implementation for keyboard keys.
87#[derive(Debug, Clone, Copy, PartialEq)]
88pub struct System<R: Debug, Keys: Index<usize, Output = Key>> {
89    keys: Keys,
90    marker: PhantomData<R>,
91}
92
93impl<R: Debug, Keys: Index<usize, Output = Key>> System<R, Keys> {
94    /// Constructs a new [System] with the given key data.
95    ///
96    /// The key data is for keys with both key codes and modifiers.
97    pub const fn new(keys: Keys) -> Self {
98        Self {
99            keys,
100            marker: PhantomData,
101        }
102    }
103}
104
105impl<R: Debug, Keys: Debug + Index<usize, Output = Key>> key::System<R> for System<R, Keys> {
106    type Ref = Ref;
107    type Context = Context;
108    type Event = Event;
109    type PendingKeyState = PendingKeyState;
110    type KeyState = KeyState;
111
112    fn new_pressed_key(
113        &self,
114        _keymap_index: u16,
115        _context: &Self::Context,
116        _key_ref: Ref,
117    ) -> (
118        key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
119        key::KeyEvents<Self::Event>,
120    ) {
121        (
122            key::PressedKeyResult::Resolved(KeyState),
123            key::KeyEvents::no_events(),
124        )
125    }
126
127    fn update_pending_state(
128        &self,
129        _pending_state: &mut Self::PendingKeyState,
130        _keymap_index: u16,
131        _context: &Self::Context,
132        _key_ref: Ref,
133        _event: key::Event<Self::Event>,
134    ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
135        panic!()
136    }
137
138    fn update_state(
139        &self,
140        _key_state: &mut Self::KeyState,
141        _ref: &Self::Ref,
142        _context: &Self::Context,
143        _keymap_index: u16,
144        _event: key::Event<Self::Event>,
145    ) -> key::KeyEvents<Self::Event> {
146        key::KeyEvents::no_events()
147    }
148
149    fn key_output(
150        &self,
151        key_ref: &Self::Ref,
152        _key_state: &Self::KeyState,
153    ) -> Option<key::KeyOutput> {
154        match key_ref {
155            Ref::KeyCode(kc) => Some(key::KeyOutput::from_key_code(*kc)),
156            Ref::Modifiers(m) => Some(key::KeyOutput::from_key_modifiers(
157                key::KeyboardModifiers::from_byte(*m),
158            )),
159            Ref::KeyCodeAndModifier(idx) => {
160                let Key {
161                    key_code,
162                    modifiers,
163                } = self.keys[*idx as usize];
164                Some(key::KeyOutput::from_key_code_with_modifiers(
165                    key_code, modifiers,
166                ))
167            }
168        }
169    }
170}
171
172#[cfg(test)]
173mod tests {
174    use super::*;
175
176    #[test]
177    fn test_sizeof_ref() {
178        assert_eq!(2, core::mem::size_of::<Ref>());
179    }
180
181    #[test]
182    fn test_sizeof_event() {
183        assert_eq!(0, core::mem::size_of::<Event>());
184    }
185}