Skip to repository content127 lines · 3.6 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T04:00:51.850Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
serial.rs
1use collections::HashMap;
2
3#[derive(Debug, Hash, PartialEq, Eq)]
4pub(crate) enum SerialKind {
5 DataDevice,
6 InputMethod,
7 MouseEnter,
8 MousePress,
9 KeyPress,
10}
11
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13pub(crate) struct Serial(u32);
14
15impl Serial {
16 pub(super) fn as_raw(self) -> u32 {
17 self.0
18 }
19}
20
21#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22pub(crate) struct SelectionSerial(Serial);
23
24impl SelectionSerial {
25 pub(super) fn as_raw(self) -> u32 {
26 self.0.as_raw()
27 }
28}
29
30#[derive(Debug)]
31/// Helper for tracking of different serial kinds.
32pub(crate) struct SerialTracker {
33 serials: HashMap<SerialKind, Serial>,
34 selection_serial: Option<SelectionSerial>,
35}
36
37impl SerialTracker {
38 pub fn new() -> Self {
39 Self {
40 serials: HashMap::default(),
41 selection_serial: None,
42 }
43 }
44
45 pub fn update(&mut self, kind: SerialKind, value: u32) {
46 let serial = Serial(value);
47
48 if matches!(&kind, SerialKind::KeyPress | SerialKind::MousePress) {
49 self.selection_serial = Some(SelectionSerial(serial));
50 }
51
52 self.serials.insert(kind, serial);
53 }
54
55 /// Returns the latest tracked serial of the provided [`SerialKind`].
56 ///
57 /// Returns a serial with a raw value of 0 if the kind has not been tracked.
58 pub fn get(&self, kind: SerialKind) -> Serial {
59 self.serials.get(&kind).copied().unwrap_or(Serial(0))
60 }
61
62 pub fn selection_serial(&self) -> Option<SelectionSerial> {
63 self.selection_serial
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 fn raw_selection_serial(serial_tracker: &SerialTracker) -> Option<u32> {
72 serial_tracker
73 .selection_serial()
74 .map(SelectionSerial::as_raw)
75 }
76
77 #[test]
78 fn test_selection_serial_ignores_unrelated_serial_kinds() {
79 let mut serial_tracker = SerialTracker::new();
80 serial_tracker.update(SerialKind::MousePress, 3783);
81 serial_tracker.update(SerialKind::InputMethod, 5011);
82 serial_tracker.update(SerialKind::KeyPress, 3787);
83 serial_tracker.update(SerialKind::MouseEnter, 6000);
84 serial_tracker.update(SerialKind::DataDevice, 7000);
85
86 assert_eq!(raw_selection_serial(&serial_tracker), Some(3787));
87 }
88
89 #[test]
90 fn test_selection_serial_uses_mouse_press_without_key_press() {
91 let mut serial_tracker = SerialTracker::new();
92 serial_tracker.update(SerialKind::MousePress, 3783);
93
94 assert_eq!(raw_selection_serial(&serial_tracker), Some(3783));
95 }
96
97 #[test]
98 fn test_selection_serial_uses_event_arrival_order_across_rollover() {
99 let mut serial_tracker = SerialTracker::new();
100 serial_tracker.update(SerialKind::KeyPress, 0xffff_fff0);
101 serial_tracker.update(SerialKind::MousePress, 0x0000_0010);
102
103 assert_eq!(raw_selection_serial(&serial_tracker), Some(0x0000_0010));
104 }
105
106 #[test]
107 fn test_selection_serial_is_unavailable_without_eligible_input() {
108 let mut serial_tracker = SerialTracker::new();
109
110 assert_eq!(raw_selection_serial(&serial_tracker), None);
111
112 serial_tracker.update(SerialKind::InputMethod, 5011);
113 serial_tracker.update(SerialKind::MouseEnter, 6000);
114 serial_tracker.update(SerialKind::DataDevice, 7000);
115
116 assert_eq!(raw_selection_serial(&serial_tracker), None);
117 }
118
119 #[test]
120 fn test_zero_is_a_valid_selection_serial() {
121 let mut serial_tracker = SerialTracker::new();
122 serial_tracker.update(SerialKind::KeyPress, 0);
123
124 assert_eq!(raw_selection_serial(&serial_tracker), Some(0));
125 }
126}
127