kll_core/
macros.rs

1// Copyright 2021 Jacob Alexander
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use heapless::spsc::Queue;
9
10use crate::{CapabilityRun, TriggerEvent};
11
12pub struct Macro<const TSIZE: usize, const CSIZE: usize> {
13    inputs: Queue<TriggerEvent, TSIZE>,
14    outputs: Queue<CapabilityRun, CSIZE>,
15}
16
17impl<const TSIZE: usize, const CSIZE: usize> Macro<TSIZE, CSIZE> {
18    pub fn new(
19        inputs: Queue<TriggerEvent, TSIZE>,
20        outputs: Queue<CapabilityRun, CSIZE>,
21    ) -> Macro<TSIZE, CSIZE> {
22        Macro { inputs, outputs }
23    }
24
25    pub fn process(&mut self) {
26        while let Some(input) = self.inputs.dequeue() {
27            self.outputs.enqueue(input.into()).unwrap();
28        }
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use heapless::spsc::Queue;
35    use kll_hid::Keyboard;
36
37    use crate::macros::Macro;
38    use crate::trigger::Phro;
39    use crate::{CapabilityEvent, CapabilityRun, TriggerEvent};
40
41    #[test]
42    fn processing_empty_input_queue_results_in_nothing_being_added_to_the_output_queue() {
43        let mut process_queue: Macro<1024, 1024> = Macro::new(Queue::new(), Queue::new());
44        assert_eq!(process_queue.inputs.len(), 0);
45        assert_eq!(process_queue.outputs.len(), 0);
46        process_queue.process();
47        assert_eq!(process_queue.inputs.len(), 0);
48        assert_eq!(process_queue.outputs.len(), 0);
49    }
50
51    #[test]
52    fn processing_an_input_queue_adds_capability_runs_to_the_output_queue() {
53        let mut inputs = Queue::new();
54        inputs.enqueue(TriggerEvent::None).unwrap();
55        inputs
56            .enqueue(TriggerEvent::Switch {
57                state: Phro::Hold,
58                index: 0,
59                last_state: 0,
60            })
61            .unwrap();
62
63        let mut process_queue: Macro<5, 5> = Macro::new(inputs, Queue::new());
64        assert_eq!(process_queue.inputs.len(), 2);
65        assert_eq!(process_queue.outputs.len(), 0);
66        process_queue.process();
67        assert_eq!(process_queue.inputs.len(), 0);
68        assert_eq!(process_queue.outputs.len(), 2);
69    }
70
71    #[test]
72    fn check_processing_events_converts_to_the_expected_output() {
73        let mut inputs = Queue::new();
74        inputs
75            .enqueue(TriggerEvent::Switch {
76                state: Phro::Press,
77                index: Keyboard::Z.into(),
78                last_state: 0,
79            })
80            .unwrap();
81
82        let mut process_queue: Macro<5, 5> = Macro::new(inputs, Queue::new());
83        process_queue.process();
84        assert_eq!(
85            process_queue.outputs.dequeue().unwrap(),
86            CapabilityRun::HidKeyboard {
87                state: CapabilityEvent::Initial,
88                id: Keyboard::Z
89            }
90        );
91    }
92}