serial.rs

 1use std::time::Instant;
 2
 3use collections::HashMap;
 4
 5#[derive(Debug, Hash, PartialEq, Eq)]
 6pub(crate) enum SerialKind {
 7    DataDevice,
 8    MouseEnter,
 9    MousePress,
10    KeyPress,
11}
12
13#[derive(Debug)]
14struct SerialData {
15    serial: u32,
16    time: Instant,
17}
18
19impl SerialData {
20    fn new(value: u32) -> Self {
21        Self {
22            serial: value,
23            time: Instant::now(),
24        }
25    }
26}
27
28#[derive(Debug)]
29/// Helper for tracking of different serial kinds.
30pub(crate) struct SerialTracker {
31    serials: HashMap<SerialKind, SerialData>,
32}
33
34impl SerialTracker {
35    pub fn new() -> Self {
36        Self {
37            serials: HashMap::default(),
38        }
39    }
40
41    pub fn update(&mut self, kind: SerialKind, value: u32) {
42        self.serials.insert(kind, SerialData::new(value));
43    }
44
45    /// Returns the latest tracked serial of the provided [`SerialKind`]
46    ///
47    /// Will return 0 if not tracked.
48    pub fn get(&self, kind: SerialKind) -> u32 {
49        self.serials
50            .get(&kind)
51            .map(|serial_data| serial_data.serial)
52            .unwrap_or(0)
53    }
54
55    /// Returns the newest serial of any of the provided [`SerialKind`]
56    pub fn get_newest_of(&self, kinds: &[SerialKind]) -> u32 {
57        kinds
58            .iter()
59            .filter_map(|kind| self.serials.get(&kind))
60            .max_by_key(|serial_data| serial_data.time)
61            .map(|serial_data| serial_data.serial)
62            .unwrap_or(0)
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_serial_tracker() {
72        let mut tracker = SerialTracker::new();
73
74        tracker.update(SerialKind::KeyPress, 100);
75        tracker.update(SerialKind::MousePress, 50);
76        tracker.update(SerialKind::MouseEnter, 300);
77
78        assert_eq!(
79            tracker.get_newest_of(&[SerialKind::KeyPress, SerialKind::MousePress]),
80            50
81        );
82        assert_eq!(tracker.get(SerialKind::DataDevice), 0);
83
84        tracker.update(SerialKind::KeyPress, 2000);
85        assert_eq!(tracker.get(SerialKind::KeyPress), 2000);
86        assert_eq!(
87            tracker.get_newest_of(&[SerialKind::KeyPress, SerialKind::MousePress]),
88            2000
89        );
90    }
91}