Skip to main content

smart_keymap/key/
layered.rs

1use core::fmt::Debug;
2use core::marker::Copy;
3use core::ops::Index;
4
5use serde::Deserialize;
6
7use crate::input;
8use crate::key;
9use crate::key::KeyboardModifiers;
10
11/// The type used for layer index.
12pub type LayerIndex = u32;
13
14/// The type used for set of active layers in ModifierKey.
15/// (Layer bit indices `0..=[MAX_BITSET_LAYER]`.)
16pub type LayerBitset = u32;
17
18/// The maximum layer bit index representable in a [LayerBitset].
19///
20/// For `LayerBitset = u32`, this is 31 (bits 0..=31, i.e. 32 layers).
21pub const MAX_BITSET_LAYER: usize = 8 * core::mem::size_of::<LayerBitset>() - 1;
22
23/// The bitset with all representable modifier layers in the mask.
24///
25/// Includes bit [MAX_BITSET_LAYER] (e.g. bit 31 for `u32`).
26pub const BITSET_MASK_ALL: LayerBitset = LayerBitset::MAX;
27
28/// Struct for modifying layers with a bitset.
29#[repr(C)]
30#[derive(Debug, Deserialize, Clone, Copy, Eq, PartialEq)]
31pub struct ModifierBitset {
32    /// The set of layers modified.
33    pub layers: LayerBitset,
34    /// The mask for which layers are affected by the modification.
35    #[serde(default = "default_modifier_bitset_mask")]
36    pub mask: LayerBitset,
37}
38
39fn default_modifier_bitset_mask() -> LayerBitset {
40    BITSET_MASK_ALL
41}
42
43/// Reference for a keyboard key.
44#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
45pub enum Ref {
46    /// Ref to a layer modifier key.
47    Modifier(u8),
48    /// Ref to a layered key.
49    Layered(u8),
50}
51
52/// Modifier layer key affects what layers are active.
53#[derive(Debug, Deserialize, Clone, Copy, PartialEq)]
54pub enum ModifierKey {
55    /// Activates the given layer when held.
56    Hold(LayerIndex, KeyboardModifiers),
57    /// Toggles whether the given layer is active when pressed.
58    Toggle(LayerIndex),
59    /// Sticky layer modifier, similar to sticky modifier key.
60    ///
61    /// Acts the same as `Hold` variant if interrupted.
62    /// If tapped, then the layer is activated for the next key tap.
63    Sticky(LayerIndex),
64    /// Sets the set of active layers to the given layers when the key is pressed.
65    SetActiveLayers(ModifierBitset),
66    /// Sets the default layer.
67    Default(LayerIndex),
68}
69
70impl ModifierKey {
71    /// Create a new [ModifierKey] that activates the given layer when held.
72    pub const fn hold(layer: LayerIndex) -> Self {
73        ModifierKey::Hold(layer, key::KeyboardModifiers::NONE)
74    }
75
76    /// Adds keyboard modifiers to a Hold modifier key.
77    pub const fn with_keyboard_modifiers(self, mods: key::KeyboardModifiers) -> Self {
78        match self {
79            ModifierKey::Hold(layer, _) => ModifierKey::Hold(layer, mods),
80            other => other,
81        }
82    }
83
84    /// Create a new [ModifierKey] that activates the layer when held, or makes it sticky when tapped.
85    pub const fn sticky(layer: LayerIndex) -> Self {
86        ModifierKey::Sticky(layer)
87    }
88
89    /// Create a new [ModifierKey] that toggles the given layer.
90    pub const fn toggle(layer: LayerIndex) -> Self {
91        ModifierKey::Toggle(layer)
92    }
93
94    /// Create a new [ModifierKey] that sets the active layers to the given slice of layers when pressed.
95    ///
96    /// Each LayerIndex in the slice must be at most [MAX_BITSET_LAYER].
97    pub const fn set_active_layers(layers: &[LayerIndex]) -> Self {
98        let mut bitset = 0;
99
100        let mut idx = 0;
101        while idx < layers.len() {
102            let layer = layers[idx] as usize;
103            if layer <= MAX_BITSET_LAYER {
104                bitset |= 1 << layer;
105            } else {
106                panic!("LayerIndex must be at most MAX_BITSET_LAYER");
107            }
108            idx += 1;
109        }
110
111        let mask = BITSET_MASK_ALL;
112        ModifierKey::SetActiveLayers(ModifierBitset {
113            layers: bitset,
114            mask,
115        })
116    }
117
118    /// Create a new [ModifierKey] that sets the active layers bitset.
119    pub const fn set_active_layers_from_bitset(bitset: LayerBitset) -> Self {
120        let mask = BITSET_MASK_ALL;
121        ModifierKey::SetActiveLayers(ModifierBitset {
122            layers: bitset,
123            mask,
124        })
125    }
126
127    /// Create a new [ModifierKey] that sets the active layers bitset.
128    pub const fn set_active_layers_from_bitset_with_mask(
129        layers: LayerBitset,
130        mask: LayerBitset,
131    ) -> Self {
132        ModifierKey::SetActiveLayers(ModifierBitset { layers, mask })
133    }
134
135    /// Create a new [ModifierKey] that sets the default layer.
136    pub const fn default(layer: LayerIndex) -> Self {
137        ModifierKey::Default(layer)
138    }
139
140    /// Create a new [input::PressedKey] and [key::ScheduledEvent] for the given keymap index.
141    ///
142    /// Pressing a [ModifierKey::Hold] emits a [LayerEvent::Activated] event.
143    pub fn new_pressed_key(&self) -> (ModifierKeyState, Option<LayerEvent>) {
144        match self {
145            ModifierKey::Hold(layer, _) => {
146                (ModifierKeyState::new(), Some(LayerEvent::Activated(*layer)))
147            }
148            ModifierKey::Toggle(layer) => {
149                (ModifierKeyState::new(), Some(LayerEvent::Toggled(*layer)))
150            }
151            ModifierKey::Sticky(layer) => (
152                ModifierKeyState::sticky(),
153                Some(LayerEvent::StickyActivated(*layer)),
154            ),
155            ModifierKey::SetActiveLayers(modifier_bitset) => (
156                ModifierKeyState::new(),
157                Some(LayerEvent::Set(*modifier_bitset)),
158            ),
159            ModifierKey::Default(layer) => (
160                ModifierKeyState::new(),
161                Some(LayerEvent::SetDefault(*layer)),
162            ),
163        }
164    }
165}
166
167impl From<LayerEvent> for () {
168    fn from(_: LayerEvent) -> Self {}
169}
170
171/// Style of activating a layer.
172#[derive(Debug, Clone, Copy, PartialEq)]
173pub enum ActivationStyle {
174    /// Regular layer activation.
175    Regular,
176    /// Sticky layer activation.
177    ///
178    /// Sticky layer activation is similar to sticky key modifiers.
179    /// The sticky layer activation is implemented using the sticky layer modifier key.
180    Sticky,
181}
182
183/// State of an individual layer: active or inactive.
184#[derive(Debug, Clone, Copy, PartialEq)]
185pub enum Activity {
186    /// The layer is active.
187    Active(ActivationStyle),
188    /// The layer is inactive.
189    Inactive,
190}
191
192impl Activity {
193    /// Returns true if the layer is active.
194    pub fn is_active(&self) -> bool {
195        matches!(self, Activity::Active(_))
196    }
197}
198
199/// Tracks state of active layers.
200pub trait LayerState: Copy + Debug {
201    /// Activate the given layer.
202    fn activate(&mut self, layer: LayerIndex, style: ActivationStyle);
203    /// Deactivate the given layer.
204    fn deactivate(&mut self, layer: LayerIndex);
205    /// Get the active layers, from highest active layer to lowest.
206    fn active_layers(&self) -> impl Iterator<Item = LayerIndex>;
207}
208
209impl<const L: usize> LayerState for [Activity; L] {
210    fn activate(&mut self, layer_index: LayerIndex, style: ActivationStyle) {
211        let layer_index: usize = layer_index as usize;
212        debug_assert!(
213            layer_index <= L,
214            "layer must be less than array length of {}",
215            L
216        );
217        self[layer_index - 1] = Activity::Active(style);
218    }
219
220    fn deactivate(&mut self, layer_index: LayerIndex) {
221        let layer_index: usize = layer_index as usize;
222        debug_assert!(
223            layer_index <= L,
224            "layer must be less than array length of {}",
225            L
226        );
227        self[layer_index - 1] = Activity::Inactive;
228    }
229
230    fn active_layers(&self) -> impl Iterator<Item = LayerIndex> {
231        self.iter().enumerate().rev().filter_map(|(i, activity)| {
232            if activity.is_active() {
233                Some(i as LayerIndex + 1)
234            } else {
235                None
236            }
237        })
238    }
239}
240
241struct ActiveLayersDebugHelper<'a, const LAYER_COUNT: usize> {
242    active_layers: &'a [Activity; LAYER_COUNT],
243}
244
245impl<const LAYER_COUNT: usize> core::fmt::Debug for ActiveLayersDebugHelper<'_, LAYER_COUNT> {
246    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
247        // Reverse-find the last Active layer to avoid printing large arrays.
248        let last_active_pos = self
249            .active_layers
250            .iter()
251            .rposition(|&pc| pc.is_active())
252            .map_or(0, |pos| pos + 1);
253        if last_active_pos < LAYER_COUNT {
254            f.debug_list()
255                .entries(&self.active_layers[..last_active_pos])
256                .finish_non_exhaustive()
257        } else {
258            f.debug_list().entries(&self.active_layers[..]).finish()
259        }
260    }
261}
262
263/// [crate::key::Context] for [LayeredKey] that tracks active layers.
264#[derive(Clone, Copy)]
265pub struct Context<const LAYER_COUNT: usize> {
266    default_layer: Option<LayerIndex>,
267    active_layers: [Activity; LAYER_COUNT],
268    // Keymap index which was pressed while a layer was sticky.
269    pressed_keymap_index: Option<u16>,
270}
271
272impl<const LAYER_COUNT: usize> Debug for Context<LAYER_COUNT> {
273    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
274        f.debug_struct("Context")
275            .field("default_layer", &self.default_layer)
276            .field(
277                "active_layers",
278                &ActiveLayersDebugHelper {
279                    active_layers: &self.active_layers,
280                },
281            )
282            .field("pressed_keymap_index", &self.pressed_keymap_index)
283            .finish()
284    }
285}
286
287impl<const LAYER_COUNT: usize> Context<LAYER_COUNT> {
288    /// Create a new [Context].
289    pub const fn new() -> Self {
290        Context {
291            default_layer: None,
292            active_layers: [Activity::Inactive; LAYER_COUNT],
293            pressed_keymap_index: None,
294        }
295    }
296}
297
298impl<const LAYER_COUNT: usize> Default for Context<LAYER_COUNT> {
299    fn default() -> Self {
300        Self::new()
301    }
302}
303
304impl<const LAYER_COUNT: usize> Context<LAYER_COUNT> {
305    /// Get the active layers.
306    pub fn layer_state(&self) -> &[Activity; LAYER_COUNT] {
307        &self.active_layers
308    }
309
310    fn sticky_layer(&self) -> Option<LayerIndex> {
311        self.active_layers
312            .iter()
313            .position(|&a| a == Activity::Active(ActivationStyle::Sticky))
314            .map(|i| i as LayerIndex + 1)
315    }
316
317    /// Updates the context with the [LayerEvent].
318    fn handle_layer_event(&mut self, event: LayerEvent) {
319        match event {
320            LayerEvent::Activated(layer) => {
321                self.active_layers.activate(layer, ActivationStyle::Regular);
322            }
323            LayerEvent::Deactivated(layer) => {
324                self.active_layers.deactivate(layer);
325            }
326            LayerEvent::StickyActivated(layer) => {
327                self.active_layers.activate(layer, ActivationStyle::Sticky);
328                self.pressed_keymap_index = None;
329            }
330            LayerEvent::Toggled(layer) => {
331                if self.active_layers[layer as usize - 1].is_active() {
332                    self.active_layers.deactivate(layer);
333                } else {
334                    self.active_layers.activate(layer, ActivationStyle::Regular);
335                }
336            }
337            LayerEvent::Set(ModifierBitset { layers, mask }) => {
338                let max_layer = 1 + LAYER_COUNT.min(MAX_BITSET_LAYER);
339
340                // layer 0 is always active.
341                for li in 1..max_layer {
342                    if (mask & (1 << li)) != 0 {
343                        if (layers & (1 << li)) != 0 {
344                            self.active_layers
345                                .activate(li as LayerIndex, ActivationStyle::Regular);
346                        } else {
347                            self.active_layers.deactivate(li as LayerIndex);
348                        }
349                    }
350                }
351            }
352            LayerEvent::SetDefault(0) => self.default_layer = None,
353            LayerEvent::SetDefault(layer) => self.default_layer = Some(layer),
354        }
355    }
356
357    /// Updates the context with the [key::Event].
358    fn handle_event(&mut self, event: key::Event<LayerEvent>) {
359        match event {
360            key::Event::Input(input::Event::Press { keymap_index, .. }) => {
361                if let Some(sticky_layer_index) = self.sticky_layer() {
362                    if self.pressed_keymap_index.is_some() {
363                        // The sticky layer modifier has already been used;
364                        // the sticky layer should be deactivated for subsequent presses.
365                        self.active_layers.deactivate(sticky_layer_index);
366                        self.pressed_keymap_index = None;
367                    } else {
368                        self.pressed_keymap_index = Some(keymap_index);
369                    }
370                }
371            }
372            key::Event::Input(input::Event::Release { keymap_index, .. }) => {
373                if let Some(sticky_layer_index) = self.sticky_layer() {
374                    if self.pressed_keymap_index == Some(keymap_index) {
375                        self.active_layers.deactivate(sticky_layer_index);
376                        self.pressed_keymap_index = None;
377                    }
378                }
379            }
380            key::Event::Key { key_event, .. } => {
381                self.handle_layer_event(key_event);
382            }
383            _ => {}
384        }
385    }
386}
387
388impl<const LAYER_COUNT: usize> key::Context for Context<LAYER_COUNT> {
389    type Event = LayerEvent;
390
391    fn handle_event(&mut self, event: key::Event<Self::Event>) -> key::KeyEvents<Self::Event> {
392        self.handle_event(event);
393        key::KeyEvents::no_events()
394    }
395}
396
397/// Errors when constructing Layers.
398#[derive(Debug, Clone, Copy, PartialEq)]
399pub enum LayersError {
400    /// Trying to construct more layers than the Layers can store.
401    Overflow,
402}
403
404impl core::fmt::Display for LayersError {
405    // This trait requires `fmt` with this exact signature.
406    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
407        write!(f, "LayersError::Overflow")
408    }
409}
410
411/// Trait for layers of [LayeredKey].
412pub trait Layers<R>: Copy + Debug {
413    /// Get the highest active key, if any, for the given [LayerState].
414    fn highest_active_key<LS: LayerState>(
415        &self,
416        layer_state: &LS,
417        default_layer: Option<LayerIndex>,
418    ) -> Option<(LayerIndex, R)>;
419    /// Constructs layers; return Err if the iterable has more keys than Layers can store.
420    fn from_iterable<I: IntoIterator<Item = Option<R>>>(keys: I) -> Result<Self, LayersError>;
421}
422
423impl<R: Copy + Debug, const L: usize> Layers<R> for [Option<R>; L] {
424    fn highest_active_key<LS: LayerState>(
425        &self,
426        layer_state: &LS,
427        default_layer: Option<LayerIndex>,
428    ) -> Option<(LayerIndex, R)> {
429        for layer_index in layer_state.active_layers() {
430            if self[layer_index as usize - 1].is_some() {
431                return self[layer_index as usize - 1].map(|k| (layer_index, k));
432            }
433        }
434
435        match default_layer {
436            Some(layer_index) if self[layer_index as usize - 1].is_some() => {
437                self[layer_index as usize - 1].map(|k| (layer_index, k))
438            }
439            _ => None,
440        }
441    }
442
443    fn from_iterable<I: IntoIterator<Item = Option<R>>>(keys: I) -> Result<Self, LayersError> {
444        let mut layered: [Option<R>; L] = [None; L];
445        for (i, maybe_key) in keys.into_iter().enumerate() {
446            if i < L {
447                layered[i] = maybe_key;
448            } else {
449                return Err(LayersError::Overflow);
450            }
451        }
452        Ok(layered)
453    }
454}
455
456/// Constructs an array of keys for the given array.
457pub const fn layered_keys<K: Copy, const L: usize, const LAYER_COUNT: usize>(
458    keys: [Option<K>; L],
459) -> [Option<K>; LAYER_COUNT] {
460    let mut layered: [Option<K>; LAYER_COUNT] = [None; LAYER_COUNT];
461
462    if L > LAYER_COUNT {
463        panic!("Too many layers for layered_keys");
464    }
465
466    let mut i = 0;
467
468    while i < L {
469        layered[i] = keys[i];
470        i += 1;
471    }
472
473    layered
474}
475
476/// A key whose behavior depends on which layer is active.
477#[derive(Debug, Deserialize, Clone, Copy, PartialEq)]
478pub struct LayeredKey<R: Copy + Debug + PartialEq, const LAYER_COUNT: usize> {
479    /// The base key, used when no layers are active.
480    pub base: R,
481    /// The layered keys, used when the corresponding layer is active.
482    #[serde(deserialize_with = "deserialize_layered")]
483    #[serde(bound(deserialize = "R: Deserialize<'de>"))]
484    pub layered: [Option<R>; LAYER_COUNT],
485}
486
487/// Deserialize a [Layers].
488fn deserialize_layered<'de, R, L: Layers<R>, D>(deserializer: D) -> Result<L, D::Error>
489where
490    R: Deserialize<'de>,
491    D: serde::Deserializer<'de>,
492{
493    let keys_vec: heapless::Vec<Option<R>, 64> = Deserialize::deserialize(deserializer)?;
494
495    L::from_iterable(keys_vec).map_err(serde::de::Error::custom)
496}
497
498impl<R: Copy + Debug + PartialEq, const LAYER_COUNT: usize> LayeredKey<R, LAYER_COUNT> {
499    /// Constructs a new [LayeredKey].
500    pub const fn new<const L: usize>(base: R, layered: [Option<R>; L]) -> Self {
501        let layered = layered_keys(layered);
502        Self { base, layered }
503    }
504}
505
506impl<R: Copy + Debug + PartialEq, const LAYER_COUNT: usize> LayeredKey<R, LAYER_COUNT> {
507    /// Presses the key, using the highest active key, if any.
508    fn new_pressed_key(&self, context: &Context<LAYER_COUNT>) -> key::NewPressedKey<R> {
509        let (_layer, passthrough_ref) = self
510            .layered
511            .highest_active_key(context.layer_state(), context.default_layer)
512            .unwrap_or((0, self.base));
513
514        key::NewPressedKey::key(passthrough_ref)
515    }
516}
517
518/// Events from [ModifierKey] which affect [Context].
519#[derive(Debug, Clone, Copy, Eq, PartialEq)]
520pub enum LayerEvent {
521    /// Activates the given layer.
522    Activated(LayerIndex),
523    /// Deactivates the given layer.
524    Deactivated(LayerIndex),
525    /// Toggles the given layer.
526    Toggled(LayerIndex),
527    /// Activates the given layer.
528    StickyActivated(LayerIndex),
529    /// Sets the active layers to the given set of layers.
530    Set(ModifierBitset),
531    /// Changes the default layer.
532    SetDefault(LayerIndex),
533}
534
535/// Struct for layer system pending key state. (No pending state).
536#[derive(Debug, Clone, Copy, PartialEq)]
537pub struct PendingKeyState;
538
539/// Whether the pressed Sticky modifier key is "sticky" or "regular".
540#[derive(Debug, Clone, Copy, Eq, PartialEq)]
541pub enum Behavior {
542    /// Key state is "sticky". (Will activate sticky modifier when released).
543    Sticky,
544    /// Key state is "regular". (No sticky modifiers activated when released).
545    Regular,
546}
547
548/// [crate::key::KeyState] of [ModifierKey].
549#[derive(Debug, Clone, Copy, PartialEq)]
550pub struct ModifierKeyState {
551    behavior: Behavior,
552}
553
554impl Default for ModifierKeyState {
555    fn default() -> Self {
556        Self::new()
557    }
558}
559
560impl ModifierKeyState {
561    /// Constructs a regular ModifierKeyState
562    pub fn new() -> Self {
563        Self {
564            behavior: Behavior::Regular,
565        }
566    }
567
568    /// Constructs a sticky ModifierKeyState
569    pub fn sticky() -> Self {
570        Self {
571            behavior: Behavior::Sticky,
572        }
573    }
574
575    /// Handle the given event for the given key.
576    pub fn handle_event(
577        &mut self,
578        keymap_index: u16,
579        event: key::Event<LayerEvent>,
580        key: &ModifierKey,
581    ) -> Option<LayerEvent> {
582        match key {
583            ModifierKey::Hold(layer, _) => match event {
584                key::Event::Input(input::Event::Release { keymap_index: ki }) => {
585                    if keymap_index == ki {
586                        Some(LayerEvent::Deactivated(*layer))
587                    } else {
588                        None
589                    }
590                }
591                _ => None,
592            },
593            ModifierKey::Toggle(_) => None,
594            ModifierKey::Sticky(layer) => match event {
595                key::Event::Input(input::Event::Press { keymap_index: _ }) => {
596                    if self.behavior == Behavior::Sticky {
597                        // Another key pressed while sticky modifier is held; make self regular
598                        self.behavior = Behavior::Regular;
599                        // Change the layer state to *regular*
600                        Some(LayerEvent::Activated(*layer))
601                    } else {
602                        None
603                    }
604                }
605                key::Event::Input(input::Event::Release { keymap_index: ki })
606                    if keymap_index == ki && self.behavior == Behavior::Regular =>
607                {
608                    Some(LayerEvent::Deactivated(*layer))
609                }
610                _ => None,
611            },
612            ModifierKey::SetActiveLayers(_modifier_bitset) => None,
613            ModifierKey::Default(layer) => match event {
614                key::Event::Input(input::Event::Release { keymap_index: ki }) => {
615                    if keymap_index == ki {
616                        Some(LayerEvent::SetDefault(*layer))
617                    } else {
618                        None
619                    }
620                }
621                _ => None,
622            },
623        }
624    }
625}
626
627/// The [key::System] implementation for layer system keys.
628#[derive(Debug, Clone, Copy, PartialEq)]
629pub struct System<
630    R: Copy + Debug + PartialEq,
631    ModifierKeys: Index<usize, Output = ModifierKey>,
632    LayeredKeys: Index<usize, Output = LayeredKey<R, LAYER_COUNT>>,
633    const LAYER_COUNT: usize,
634> {
635    modifier_keys: ModifierKeys,
636    layered_keys: LayeredKeys,
637}
638
639impl<
640        R: Copy + Debug + PartialEq,
641        ModifierKeys: Index<usize, Output = ModifierKey>,
642        LayeredKeys: Index<usize, Output = LayeredKey<R, LAYER_COUNT>>,
643        const LAYER_COUNT: usize,
644    > System<R, ModifierKeys, LayeredKeys, LAYER_COUNT>
645{
646    /// Constructs a new [System] with the given key data.
647    pub const fn new(modifier_keys: ModifierKeys, layered_keys: LayeredKeys) -> Self {
648        Self {
649            modifier_keys,
650            layered_keys,
651        }
652    }
653}
654
655impl<
656        R: Copy + Debug + PartialEq,
657        ModifierKeys: Debug + Index<usize, Output = ModifierKey>,
658        LayeredKeys: Debug + Index<usize, Output = LayeredKey<R, LAYER_COUNT>>,
659        const LAYER_COUNT: usize,
660    > key::System<R> for System<R, ModifierKeys, LayeredKeys, LAYER_COUNT>
661{
662    type Ref = Ref;
663    type Context = Context<LAYER_COUNT>;
664    type Event = LayerEvent;
665    type PendingKeyState = PendingKeyState;
666    type KeyState = ModifierKeyState;
667
668    fn new_pressed_key(
669        &self,
670        keymap_index: u16,
671        context: &Self::Context,
672        key_ref: Ref,
673    ) -> (
674        key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
675        key::KeyEvents<Self::Event>,
676    ) {
677        match key_ref {
678            Ref::Modifier(mod_key_index) => {
679                let key = self.modifier_keys[mod_key_index as usize];
680                let (m_ks, maybe_lmod_ev) = key.new_pressed_key();
681                let pks = key::PressedKeyResult::Resolved(m_ks);
682                let pke = match maybe_lmod_ev {
683                    Some(lmod_ev) => {
684                        key::KeyEvents::event(key::Event::key_event(keymap_index, lmod_ev))
685                    }
686                    None => key::KeyEvents::no_events(),
687                };
688                (pks, pke)
689            }
690            Ref::Layered(i) => {
691                let key = &self.layered_keys[i as usize];
692                let npk = key.new_pressed_key(context);
693                (
694                    key::PressedKeyResult::NewPressedKey(npk),
695                    key::KeyEvents::no_events(),
696                )
697            }
698        }
699    }
700
701    fn update_pending_state(
702        &self,
703        _pending_state: &mut Self::PendingKeyState,
704        _keymap_index: u16,
705        _context: &Self::Context,
706        _key_ref: Ref,
707        _event: key::Event<Self::Event>,
708    ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
709        panic!()
710    }
711
712    fn update_state(
713        &self,
714        key_state: &mut Self::KeyState,
715        key_ref: &Self::Ref,
716        _context: &Self::Context,
717        keymap_index: u16,
718        event: key::Event<Self::Event>,
719    ) -> key::KeyEvents<Self::Event> {
720        match key_ref {
721            Ref::Modifier(mod_key_index) => {
722                let mod_key = &self.modifier_keys[*mod_key_index as usize];
723                let maybe_ev = key_state.handle_event(keymap_index, event, mod_key);
724                maybe_ev.map_or(key::KeyEvents::no_events(), |ev| {
725                    key::KeyEvents::event(key::Event::key_event(keymap_index, ev))
726                })
727            }
728            _ => key::KeyEvents::no_events(),
729        }
730    }
731
732    fn key_output(
733        &self,
734        key_ref: &Self::Ref,
735        _key_state: &Self::KeyState,
736    ) -> Option<key::KeyOutput> {
737        if let Ref::Modifier(mod_key_index) = key_ref {
738            let key = self.modifier_keys[*mod_key_index as usize];
739            match key {
740                ModifierKey::Hold(_, mods) if mods != key::KeyboardModifiers::NONE => {
741                    Some(key::KeyOutput::from_key_modifiers(mods))
742                }
743                _ => None,
744            }
745        } else {
746            None
747        }
748    }
749}
750
751#[cfg(test)]
752#[allow(clippy::unwrap_used, clippy::expect_used)]
753mod tests {
754    use super::*;
755
756    use crate::key::keyboard;
757
758    use crate::key::System as _;
759
760    const LAYER_COUNT: usize = 8;
761
762    type Context = super::Context<LAYER_COUNT>;
763
764    #[test]
765    fn test_sizeof_ref() {
766        assert_eq!(2, core::mem::size_of::<Ref>());
767    }
768
769    #[test]
770    fn test_sizeof_modifier_bitset() {
771        assert_eq!(8, core::mem::size_of::<ModifierBitset>());
772    }
773
774    #[test]
775    fn test_sizeof_event() {
776        // Firmware RAM budget on 32-bit targets: LayerEvent::Set is a ModifierBitset.
777        assert_eq!(12, core::mem::size_of::<LayerEvent>());
778    }
779
780    #[test]
781    fn deserialize_set_active_layers_record_json() {
782        let key: ModifierKey =
783            serde_json::from_str(r#"{"SetActiveLayers": {"layers": 5, "mask": 3}}"#).unwrap();
784        assert_eq!(
785            ModifierKey::SetActiveLayers(ModifierBitset { layers: 5, mask: 3 }),
786            key,
787        );
788
789        let key: ModifierKey =
790            serde_json::from_str(r#"{"SetActiveLayers": {"layers": 5}}"#).unwrap();
791        assert_eq!(
792            ModifierKey::SetActiveLayers(ModifierBitset {
793                layers: 5,
794                mask: BITSET_MASK_ALL,
795            }),
796            key,
797        );
798    }
799
800    #[test]
801    fn test_pressing_hold_modifier_key_emits_event_activate_layer() {
802        let layer = 1;
803        let key = ModifierKey::hold(layer);
804
805        let (_pressed_key, layer_event) = key.new_pressed_key();
806
807        assert_eq!(Some(LayerEvent::Activated(layer)), layer_event);
808    }
809
810    #[test]
811    fn test_releasing_hold_modifier_key_emits_event_deactivate_layer() {
812        // Assemble: press a Hold layer modifier key
813        let layer = 1;
814        let key = ModifierKey::hold(layer);
815        let keymap_index = 9; // arbitrary
816        let (mut pressed_key_state, _) = key.new_pressed_key();
817
818        // Act: the modifier key handles "release key" input event
819        let actual_events = pressed_key_state
820            .handle_event(
821                keymap_index,
822                key::Event::Input(input::Event::Release { keymap_index }),
823                &key,
824            )
825            .into_iter()
826            .next();
827
828        // Assert: the pressed key should have emitted a layer deactivation event
829        let first_ev = actual_events.into_iter().next();
830        if let Some(actual_layer_event) = first_ev {
831            let expected_layer_event = LayerEvent::Deactivated(layer);
832            assert_eq!(expected_layer_event, actual_layer_event);
833        } else {
834            panic!("Expected Some LayerDeactivated event");
835        }
836    }
837
838    #[test]
839    fn test_releasing_different_hold_modifier_key_does_not_emit_event() {
840        // Assemble: press a Hold layer modifier key
841        let layer = 1;
842        let key = ModifierKey::hold(layer);
843        let keymap_index = 9; // arbitrary
844        let (mut pressed_key_state, _) = key.new_pressed_key();
845
846        // Act: the modifier key handles "release key" input event for a different key
847        let different_keymap_index = keymap_index + 1;
848        let different_key_released_ev = key::Event::Input(input::Event::Release {
849            keymap_index: different_keymap_index,
850        });
851        let actual_events = pressed_key_state
852            .handle_event(keymap_index, different_key_released_ev, &key)
853            .into_iter()
854            .next();
855
856        // Assert: the pressed key should not emit an event
857        if actual_events.is_some() {
858            panic!("Expected no event emitted");
859        }
860    }
861
862    #[test]
863    fn test_context_handling_event_adjusts_active_layers() {
864        let mut context = Context::default();
865
866        context.handle_layer_event(LayerEvent::Activated(2));
867
868        let actual_active_layers = &context.active_layers[0..3];
869        assert_eq!(
870            &[
871                Activity::Inactive,
872                Activity::Active(ActivationStyle::Regular),
873                Activity::Inactive
874            ],
875            actual_active_layers
876        );
877    }
878
879    #[test]
880    fn test_pressing_layered_key_acts_as_base_key_when_no_layers_active() {
881        // Assemble
882        let context = Context::default();
883        let expected_ref = keyboard::Ref::KeyCode(0x04);
884        let layered_key = LayeredKey::new(
885            expected_ref,
886            [
887                Some(keyboard::Ref::KeyCode(0x05)),
888                Some(keyboard::Ref::KeyCode(0x06)),
889                Some(keyboard::Ref::KeyCode(0x07)),
890            ],
891        );
892        let system = System::new([], [layered_key]);
893
894        // Act: without activating a layer, press the layered key
895        let keymap_index = 9; // arbitrary
896        let key_ref = Ref::Layered(0);
897        let (pkr, _pke) = system.new_pressed_key(keymap_index, &context, key_ref);
898
899        // Assert
900        let expected_pkr =
901            key::PressedKeyResult::NewPressedKey(key::NewPressedKey::Key(expected_ref));
902        assert_eq!(expected_pkr, pkr,);
903    }
904
905    // Terminology:
906    //   "defined layer" = LayeredKey.layered[] is Some for that layer;
907    //   "active layer" = Context.active_layers[] = true for that layer.
908
909    #[test]
910    fn test_pressing_layered_key_falls_through_undefined_active_layers() {
911        // Assemble: layered key (with no layered definitions)
912        let mut context = Context::default();
913        let expected_ref = keyboard::Ref::KeyCode(0x04);
914        let layered_key = LayeredKey::new(expected_ref, [None, None, None]);
915        let system = System::new([], [layered_key]);
916
917        // Act: activate all layers, press layered key
918        context.handle_layer_event(LayerEvent::Activated(1));
919        context.handle_layer_event(LayerEvent::Activated(2));
920        context.handle_layer_event(LayerEvent::Activated(3));
921        let keymap_index = 9; // arbitrary
922        let key_ref = Ref::Layered(0);
923        let (pkr, _pke) = system.new_pressed_key(keymap_index, &context, key_ref);
924
925        // Assert
926        let expected_pkr =
927            key::PressedKeyResult::NewPressedKey(key::NewPressedKey::Key(expected_ref));
928        assert_eq!(expected_pkr, pkr,);
929    }
930
931    #[test]
932    fn test_pressing_layered_key_acts_as_highest_defined_active_layer() {
933        // Assemble: layered key (with no layered definitions)
934        let mut context = Context::default();
935        let expected_ref = keyboard::Ref::KeyCode(0x09);
936        let layered_key = LayeredKey::new(
937            keyboard::Ref::KeyCode(0x04),
938            [
939                Some(keyboard::Ref::KeyCode(0x05)),
940                Some(keyboard::Ref::KeyCode(0x06)),
941                Some(expected_ref),
942            ],
943        );
944        let system = System::new([], [layered_key]);
945
946        // Act: activate all layers, press layered key
947        context.handle_layer_event(LayerEvent::Activated(1));
948        context.handle_layer_event(LayerEvent::Activated(2));
949        context.handle_layer_event(LayerEvent::Activated(3));
950        let keymap_index = 9; // arbitrary
951        let key_ref = Ref::Layered(0);
952        let (pkr, _pke) = system.new_pressed_key(keymap_index, &context, key_ref);
953
954        // Assert
955        let expected_pkr =
956            key::PressedKeyResult::NewPressedKey(key::NewPressedKey::Key(expected_ref));
957        assert_eq!(expected_pkr, pkr,);
958    }
959
960    #[test]
961    fn test_pressing_layered_key_with_some_transparency_acts_as_highest_defined_active_layer() {
962        // Assemble: layered key (with no layered definitions)
963        let mut context = Context::default();
964        let expected_ref = keyboard::Ref::KeyCode(0x09);
965        let layered_key = LayeredKey::new(
966            keyboard::Ref::KeyCode(0x04),
967            [Some(expected_ref), Some(keyboard::Ref::KeyCode(0x06)), None],
968        );
969        let system = System::new([], [layered_key]);
970
971        // Act: activate all layers, press layered key
972        context.handle_layer_event(LayerEvent::Activated(1));
973        context.handle_layer_event(LayerEvent::Activated(3));
974        let keymap_index = 9; // arbitrary
975        let key_ref = Ref::Layered(0);
976        let (pkr, _pke) = system.new_pressed_key(keymap_index, &context, key_ref);
977
978        // Assert
979        let expected_pkr =
980            key::PressedKeyResult::NewPressedKey(key::NewPressedKey::Key(expected_ref));
981        assert_eq!(expected_pkr, pkr,);
982    }
983
984    #[test]
985    fn test_layer_state_array_active_layers() {
986        let mut layer_state: [Activity; 5] = [Activity::Inactive; 5];
987        layer_state.activate(1, ActivationStyle::Regular);
988        layer_state.activate(2, ActivationStyle::Regular);
989        layer_state.activate(4, ActivationStyle::Regular);
990        let actual_active_layers: Vec<LayerIndex> = layer_state.active_layers().collect();
991        let expected_active_layers: Vec<LayerIndex> = vec![4, 2, 1];
992
993        assert_eq!(expected_active_layers, actual_active_layers);
994    }
995
996    #[test]
997    fn test_pressing_toggle_modifier_key_emits_event_layer_toggled() {
998        // Assemble
999        let layer = 1;
1000        let key = ModifierKey::Toggle(layer);
1001
1002        // Act
1003        let (_pressed_key, layer_event) = key.new_pressed_key();
1004
1005        // Assert
1006        assert_eq!(Some(LayerEvent::Toggled(layer)), layer_event);
1007    }
1008}