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