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