hojicha_runtime/
safe_priority.rs1use crate::priority_queue::Priority;
7use hojicha_core::core::Message;
8use hojicha_core::event::Event;
9
10pub fn detect_priority<M: Message>(event: &Event<M>) -> Priority {
12 if event.is_quit() || event.is_key() || event.is_suspend() || event.is_resume() {
14 Priority::High
15 } else if event.is_resize() || event.is_tick() {
16 Priority::Low
17 } else {
18 Priority::Normal
19 }
20}
21
22#[derive(Debug, Clone)]
27pub enum EventKind {
28 Quit,
30 Key,
32 Mouse,
34 User,
36 Resize,
38 Tick,
40 Paste,
42 Focus,
44 Blur,
46 Suspend,
48 Resume,
50 ExecProcess,
52}
53
54impl EventKind {
55 pub fn priority(&self) -> Priority {
57 match self {
58 EventKind::Quit => Priority::High,
59 EventKind::Key => Priority::High,
60 EventKind::Suspend => Priority::High,
61 EventKind::Resume => Priority::High,
62
63 EventKind::Mouse => Priority::Normal,
64 EventKind::User => Priority::Normal,
65 EventKind::Paste => Priority::Normal,
66 EventKind::Focus => Priority::Normal,
67 EventKind::Blur => Priority::Normal,
68 EventKind::ExecProcess => Priority::Normal,
69
70 EventKind::Resize => Priority::Low,
71 EventKind::Tick => Priority::Low,
72 }
73 }
74
75 pub fn from_event<M: Message>(event: &Event<M>) -> Self {
77 if event.is_quit() { EventKind::Quit }
78 else if event.is_key() { EventKind::Key }
79 else if event.is_mouse() { EventKind::Mouse }
80 else if event.is_user() { EventKind::User }
81 else if event.is_resize() { EventKind::Resize }
82 else if event.is_tick() { EventKind::Tick }
83 else if event.is_paste() { EventKind::Paste }
84 else if event.is_focus() { EventKind::Focus }
85 else if event.is_blur() { EventKind::Blur }
86 else if event.is_suspend() { EventKind::Suspend }
87 else if event.is_resume() { EventKind::Resume }
88 else { EventKind::ExecProcess }
89 }
90}
91
92pub trait SafePriorityMapper<M: Message>: Send + Sync {
94 fn map_priority(&self, event: &Event<M>) -> Priority;
96}
97
98pub struct DefaultPriorityMapper;
100
101impl<M: Message> SafePriorityMapper<M> for DefaultPriorityMapper {
102 fn map_priority(&self, event: &Event<M>) -> Priority {
103 detect_priority(event)
104 }
105}
106
107pub struct CustomPriorityMapper<M: Message> {
109 mapper: Box<dyn Fn(&Event<M>) -> Option<Priority> + Send + Sync>,
110}
111
112impl<M: Message> CustomPriorityMapper<M> {
113 pub fn new<F>(mapper: F) -> Self
115 where
116 F: Fn(&Event<M>) -> Option<Priority> + Send + Sync + 'static,
117 {
118 Self {
119 mapper: Box::new(mapper),
120 }
121 }
122}
123
124impl<M: Message> SafePriorityMapper<M> for CustomPriorityMapper<M> {
125 fn map_priority(&self, event: &Event<M>) -> Priority {
126 (self.mapper)(event).unwrap_or_else(|| detect_priority(event))
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134 use hojicha_core::event::{Event, Key, KeyEvent, KeyModifiers};
135
136 #[test]
137 fn test_priority_detection() {
138 assert_eq!(detect_priority::<()>(&Event::Quit), Priority::High);
140 assert_eq!(
141 detect_priority::<()>(&Event::Key(KeyEvent::new(
142 Key::Char('a'),
143 KeyModifiers::empty()
144 ))),
145 Priority::High
146 );
147
148 assert_eq!(
150 detect_priority::<String>(&Event::User("test".to_string())),
151 Priority::Normal
152 );
153
154 assert_eq!(detect_priority::<()>(&Event::Tick), Priority::Low);
156 assert_eq!(
157 detect_priority::<()>(&Event::Resize {
158 width: 80,
159 height: 24
160 }),
161 Priority::Low
162 );
163 }
164
165 #[test]
166 fn test_event_kind() {
167 let quit_event: Event<()> = Event::Quit;
168 assert_eq!(
169 EventKind::from_event(&quit_event).priority(),
170 Priority::High
171 );
172
173 let tick_event: Event<()> = Event::Tick;
174 assert_eq!(EventKind::from_event(&tick_event).priority(), Priority::Low);
175 }
176
177 #[test]
178 fn test_custom_mapper() {
179 let mapper = CustomPriorityMapper::new(|event| {
181 if event.is_user() {
182 Some(Priority::High)
183 } else {
184 None
185 }
186 });
187
188 let user_event = Event::User("important".to_string());
189 assert_eq!(mapper.map_priority(&user_event), Priority::High);
190
191 let tick_event: Event<String> = Event::Tick;
192 assert_eq!(mapper.map_priority(&tick_event), Priority::Low);
193 }
194}