1#![no_std]
2#![deny(missing_docs, clippy::unwrap_used)]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4#![doc = include_str!("../README.md")]
5
6extern crate alloc;
7#[cfg(feature = "std")]
8extern crate std;
9
10#[cfg(feature = "std")]
11mod encoder;
12mod key;
13mod mouse;
14#[cfg(feature = "std")]
15mod parser;
16
17use alloc::string::String;
18use core::error::Error;
19use core::fmt;
20
21#[cfg(feature = "std")]
22pub use encoder::*;
23pub use key::*;
24pub use mouse::*;
25
26#[derive(Debug)]
28pub struct UnsupportedEvent(pub String);
29
30impl fmt::Display for UnsupportedEvent {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 write!(f, "Unsupported event: {}", self.0)
33 }
34}
35
36impl Error for UnsupportedEvent {}
37
38#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Hash)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41pub enum Event {
42 FocusGained,
44 FocusLost,
46 Key(KeyEvent),
48 Mouse(MouseEvent),
50 Paste(String),
52 Resize {
54 rows: u32,
56 cols: u32,
58 },
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub enum Repeats {
64 Include,
66 Exclude,
68}
69
70impl Event {
71 pub fn as_key(&self) -> Option<KeyEvent> {
73 if let Self::Key(key_event) = self {
74 Some(*key_event)
75 } else {
76 None
77 }
78 }
79
80 pub fn is_key(&self) -> bool {
82 self.as_key().is_some()
83 }
84
85 pub fn as_key_press(&self, repeats: Repeats) -> Option<KeyEvent> {
92 if repeats == Repeats::Include {
93 if let Self::Key(
94 key_event @ KeyEvent {
95 kind: KeyEventKind::Press | KeyEventKind::Repeat,
96 ..
97 },
98 ) = self
99 {
100 Some(*key_event)
101 } else {
102 None
103 }
104 } else if let Self::Key(
105 key_event @ KeyEvent {
106 kind: KeyEventKind::Press,
107 ..
108 },
109 ) = self
110 {
111 Some(*key_event)
112 } else {
113 None
114 }
115 }
116
117 pub fn is_key_press(&self, repeats: Repeats) -> bool {
124 self.as_key_press(repeats).is_some()
125 }
126
127 pub fn as_key_repeat(&self) -> Option<KeyEvent> {
129 if let Self::Key(
130 key_event @ KeyEvent {
131 kind: KeyEventKind::Repeat,
132 ..
133 },
134 ) = self
135 {
136 Some(*key_event)
137 } else {
138 None
139 }
140 }
141
142 pub fn is_key_repeat(&self) -> bool {
144 self.as_key_repeat().is_some()
145 }
146
147 pub fn as_key_release(&self) -> Option<KeyEvent> {
149 if let Self::Key(
150 key_event @ KeyEvent {
151 kind: KeyEventKind::Release,
152 ..
153 },
154 ) = self
155 {
156 Some(*key_event)
157 } else {
158 None
159 }
160 }
161
162 pub fn is_key_release(&self) -> bool {
164 self.as_key_release().is_some()
165 }
166
167 pub fn as_mouse(&self) -> Option<MouseEvent> {
169 if let Self::Mouse(mouse_event) = self {
170 Some(*mouse_event)
171 } else {
172 None
173 }
174 }
175
176 pub fn is_mouse(&self) -> bool {
178 self.as_mouse().is_some()
179 }
180
181 pub fn as_mouse_down(&self) -> Option<(MouseEvent, MouseButton)> {
183 if let Self::Mouse(
184 mouse_event @ MouseEvent {
185 kind: MouseEventKind::Down(button),
186 ..
187 },
188 ) = self
189 {
190 Some((*mouse_event, *button))
191 } else {
192 None
193 }
194 }
195
196 pub fn is_mouse_down(&self) -> bool {
198 self.as_mouse_down().is_some()
199 }
200
201 pub fn as_mouse_up(&self) -> Option<(MouseEvent, MouseButton)> {
203 if let Self::Mouse(
204 mouse_event @ MouseEvent {
205 kind: MouseEventKind::Up(button),
206 ..
207 },
208 ) = self
209 {
210 Some((*mouse_event, *button))
211 } else {
212 None
213 }
214 }
215
216 pub fn is_mouse_up(&self) -> bool {
218 self.as_mouse_up().is_some()
219 }
220
221 pub fn as_mouse_drag(&self) -> Option<(MouseEvent, MouseButton)> {
223 if let Self::Mouse(
224 mouse_event @ MouseEvent {
225 kind: MouseEventKind::Drag(button),
226 ..
227 },
228 ) = self
229 {
230 Some((*mouse_event, *button))
231 } else {
232 None
233 }
234 }
235
236 pub fn is_mouse_drag(&self) -> bool {
238 self.as_mouse_drag().is_some()
239 }
240
241 pub fn as_mouse_move(&self) -> Option<MouseEvent> {
243 if let Self::Mouse(
244 mouse_event @ MouseEvent {
245 kind: MouseEventKind::Moved,
246 ..
247 },
248 ) = self
249 {
250 Some(*mouse_event)
251 } else {
252 None
253 }
254 }
255
256 pub fn is_mouse_move(&self) -> bool {
258 self.as_mouse_move().is_some()
259 }
260
261 pub fn as_mouse_scroll(&self) -> Option<(MouseEvent, ScrollDirection)> {
263 if let Self::Mouse(
264 mouse_event @ MouseEvent {
265 kind: MouseEventKind::Scroll(direction),
266 ..
267 },
268 ) = self
269 {
270 Some((*mouse_event, *direction))
271 } else {
272 None
273 }
274 }
275
276 pub fn is_mouse_scroll(&self) -> bool {
278 self.as_mouse_scroll().is_some()
279 }
280
281 pub fn is_focus_gained(&self) -> bool {
283 *self == Self::FocusGained
284 }
285
286 pub fn is_focus_lost(&self) -> bool {
288 *self == Self::FocusLost
289 }
290
291 pub fn as_paste(&self) -> Option<&str> {
293 if let Self::Paste(text) = self {
294 Some(text)
295 } else {
296 None
297 }
298 }
299
300 pub fn is_paste(&self) -> bool {
302 self.as_paste().is_some()
303 }
304
305 pub fn as_resize(&self) -> Option<(u32, u32)> {
307 if let Self::Resize { rows, cols } = self {
308 Some((*rows, *cols))
309 } else {
310 None
311 }
312 }
313
314 pub fn is_resize(&self) -> bool {
316 self.as_resize().is_some()
317 }
318}