1use crate::event::InternalEvent;
2
3/// Interface for filtering an `InternalEvent`.
4pub(crate) trait Filter: Send + Sync + 'static {
5 /// Returns whether the given event fulfills the filter.
6 fn eval(&self, event: &InternalEvent) -> bool;
7}
8
9#[cfg(unix)]
10#[derive(Debug, Clone)]
11pub(crate) struct CursorPositionFilter;
12
13#[cfg(unix)]
14impl Filter for CursorPositionFilter {
15 fn eval(&self, event: &InternalEvent) -> bool {
16 matches!(*event, InternalEvent::CursorPosition(_, _))
17 }
18}
19
20#[cfg(unix)]
21#[derive(Debug, Clone)]
22pub(crate) struct KeyboardEnhancementFlagsFilter;
23
24#[cfg(unix)]
25impl Filter for KeyboardEnhancementFlagsFilter {
26 fn eval(&self, event: &InternalEvent) -> bool {
27 // This filter checks for either a KeyboardEnhancementFlags response or
28 // a PrimaryDeviceAttributes response. If we receive the PrimaryDeviceAttributes
29 // response but not KeyboardEnhancementFlags, the terminal does not support
30 // progressive keyboard enhancement.
31 matches!(
32 *event,
33 InternalEvent::KeyboardEnhancementFlags(_) | InternalEvent::PrimaryDeviceAttributes
34 )
35 }
36}
37
38#[cfg(unix)]
39#[derive(Debug, Clone)]
40pub(crate) struct PrimaryDeviceAttributesFilter;
41
42#[cfg(unix)]
43impl Filter for PrimaryDeviceAttributesFilter {
44 fn eval(&self, event: &InternalEvent) -> bool {
45 matches!(*event, InternalEvent::PrimaryDeviceAttributes)
46 }
47}
48
49#[derive(Debug, Clone)]
50pub(crate) struct EventFilter;
51
52impl Filter for EventFilter {
53 #[cfg(unix)]
54 fn eval(&self, event: &InternalEvent) -> bool {
55 matches!(*event, InternalEvent::Event(_))
56 }
57
58 #[cfg(windows)]
59 fn eval(&self, _: &InternalEvent) -> bool {
60 true
61 }
62}
63
64#[derive(Debug, Clone)]
65pub(crate) struct InternalEventFilter;
66
67impl Filter for InternalEventFilter {
68 fn eval(&self, _: &InternalEvent) -> bool {
69 true
70 }
71}
72
73#[cfg(test)]
74#[cfg(unix)]
75mod tests {
76 use super::{
77 super::Event, CursorPositionFilter, EventFilter, Filter, InternalEvent,
78 InternalEventFilter, KeyboardEnhancementFlagsFilter, PrimaryDeviceAttributesFilter,
79 };
80
81 #[test]
82 fn test_cursor_position_filter_filters_cursor_position() {
83 assert!(!CursorPositionFilter.eval(&InternalEvent::Event(Event::Resize(10, 10))));
84 assert!(CursorPositionFilter.eval(&InternalEvent::CursorPosition(0, 0)));
85 }
86
87 #[test]
88 fn test_keyboard_enhancement_status_filter_filters_keyboard_enhancement_status() {
89 assert!(!KeyboardEnhancementFlagsFilter.eval(&InternalEvent::Event(Event::Resize(10, 10))));
90 assert!(
91 KeyboardEnhancementFlagsFilter.eval(&InternalEvent::KeyboardEnhancementFlags(
92 crate::event::KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
93 ))
94 );
95 assert!(KeyboardEnhancementFlagsFilter.eval(&InternalEvent::PrimaryDeviceAttributes));
96 }
97
98 #[test]
99 fn test_primary_device_attributes_filter_filters_primary_device_attributes() {
100 assert!(!PrimaryDeviceAttributesFilter.eval(&InternalEvent::Event(Event::Resize(10, 10))));
101 assert!(PrimaryDeviceAttributesFilter.eval(&InternalEvent::PrimaryDeviceAttributes));
102 }
103
104 #[test]
105 fn test_event_filter_filters_events() {
106 assert!(EventFilter.eval(&InternalEvent::Event(Event::Resize(10, 10))));
107 assert!(!EventFilter.eval(&InternalEvent::CursorPosition(0, 0)));
108 }
109
110 #[test]
111 fn test_event_filter_filters_internal_events() {
112 assert!(InternalEventFilter.eval(&InternalEvent::Event(Event::Resize(10, 10))));
113 assert!(InternalEventFilter.eval(&InternalEvent::CursorPosition(0, 0)));
114 }
115}
116