1use alloc::vec::Vec;
5use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct KeyModifiers(u8);
15
16impl KeyModifiers {
17 pub const NONE: Self = Self(0);
19 pub const SHIFT: Self = Self(1 << 0);
21 pub const CONTROL: Self = Self(1 << 1);
23 pub const ALT: Self = Self(1 << 2);
25 pub const SUPER: Self = Self(1 << 3);
27
28 #[must_use]
34 pub const fn from_bits_truncate(bits: u8) -> Self {
35 Self(bits & 0b1111)
36 }
37
38 #[must_use]
44 #[allow(clippy::fn_params_excessive_bools)]
46 pub const fn from_parts(shift: bool, control: bool, alt: bool, super_: bool) -> Self {
47 Self((shift as u8) | (control as u8) << 1 | (alt as u8) << 2 | (super_ as u8) << 3)
48 }
49
50 #[must_use]
53 pub const fn bits(self) -> u8 {
54 self.0
55 }
56
57 #[must_use]
59 pub const fn contains(self, other: Self) -> bool {
60 (self.0 & other.0) == other.0
61 }
62
63 #[must_use]
65 pub const fn is_empty(self) -> bool {
66 self.0 == 0
67 }
68}
69
70impl BitOr for KeyModifiers {
71 type Output = Self;
72 fn bitor(self, rhs: Self) -> Self {
73 Self(self.0 | rhs.0)
74 }
75}
76
77impl BitOrAssign for KeyModifiers {
78 fn bitor_assign(&mut self, rhs: Self) {
79 self.0 |= rhs.0;
80 }
81}
82
83impl BitAnd for KeyModifiers {
84 type Output = Self;
85 fn bitand(self, rhs: Self) -> Self {
86 Self(self.0 & rhs.0)
87 }
88}
89
90impl BitAndAssign for KeyModifiers {
91 fn bitand_assign(&mut self, rhs: Self) {
92 self.0 &= rhs.0;
93 }
94}
95
96impl Not for KeyModifiers {
97 type Output = Self;
98 fn not(self) -> Self {
99 Self(!self.0 & 0b1111)
102 }
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
106#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
107#[non_exhaustive]
108pub enum ModifierKey {
119 Shift,
121 Control,
123 Alt,
125 Super,
127}
128
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
130#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
131#[non_exhaustive]
132pub enum KeyCode {
134 Char(char),
136 F(u8),
138 Backspace,
140 Enter,
142 Left,
144 Right,
146 Up,
148 Down,
150 Home,
152 End,
154 PageUp,
156 PageDown,
158 Tab,
160 BackTab,
162 Delete,
164 Insert,
166 Escape,
168 Modifier(ModifierKey),
171 CapsLock,
173 ScrollLock,
175 NumLock,
177 PrintScreen,
179 Pause,
181 Menu,
183}
184
185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
186#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
187#[non_exhaustive]
188pub enum KeyEventKind {
203 #[default]
205 Press,
206 Repeat,
208 Release,
210}
211
212#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
213#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
214#[non_exhaustive]
215pub enum KeyLocation {
222 #[default]
225 Standard,
226 Left,
228 Right,
230 Numpad,
232}
233
234#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
235#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
236#[non_exhaustive]
237pub struct KeyEvent {
239 pub code: KeyCode,
241 pub modifiers: KeyModifiers,
243 pub kind: KeyEventKind,
248 pub location: KeyLocation,
252}
253
254impl KeyEvent {
255 #[must_use]
258 pub const fn new(code: KeyCode, modifiers: KeyModifiers) -> Self {
259 Self {
260 code,
261 modifiers,
262 kind: KeyEventKind::Press,
263 location: KeyLocation::Standard,
264 }
265 }
266
267 #[must_use]
269 pub const fn with_kind(code: KeyCode, modifiers: KeyModifiers, kind: KeyEventKind) -> Self {
270 Self {
271 code,
272 modifiers,
273 kind,
274 location: KeyLocation::Standard,
275 }
276 }
277
278 #[must_use]
280 pub const fn with_location(
281 code: KeyCode,
282 modifiers: KeyModifiers,
283 kind: KeyEventKind,
284 location: KeyLocation,
285 ) -> Self {
286 Self {
287 code,
288 modifiers,
289 kind,
290 location,
291 }
292 }
293
294 #[must_use]
297 pub const fn is_down(self) -> bool {
298 matches!(self.kind, KeyEventKind::Press | KeyEventKind::Repeat)
299 }
300}
301
302#[derive(Debug, Clone, Default)]
324#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
325pub struct KeyState {
326 held: Vec<(KeyCode, KeyLocation)>,
327}
328
329impl KeyState {
330 #[must_use]
332 pub const fn new() -> Self {
333 Self { held: Vec::new() }
334 }
335
336 pub fn apply(&mut self, event: KeyEvent) {
341 let entry = (event.code, event.location);
342 match event.kind {
343 KeyEventKind::Press | KeyEventKind::Repeat => {
344 if !self.held.contains(&entry) {
345 self.held.push(entry);
346 }
347 }
348 KeyEventKind::Release => {
349 self.held.retain(|&e| e != entry);
350 }
351 }
352 }
353
354 pub fn apply_event(&mut self, event: &super::Event) {
360 match event {
361 super::Event::Key(key) => self.apply(*key),
362 super::Event::FocusLost => self.clear(),
363 _ => {}
364 }
365 }
366
367 #[must_use]
369 pub fn is_held(&self, code: KeyCode, location: KeyLocation) -> bool {
370 self.held.contains(&(code, location))
371 }
372
373 pub fn held(&self) -> impl Iterator<Item = (KeyCode, KeyLocation)> + '_ {
375 self.held.iter().copied()
376 }
377
378 pub fn clear(&mut self) {
380 self.held.clear();
381 }
382}
383
384#[cfg(test)]
385mod tests {
386 use super::super::Event;
387 use super::*;
388 use alloc::vec;
389
390 #[test]
391 fn test_key_modifiers() {
392 let mods = KeyModifiers::SHIFT | KeyModifiers::CONTROL;
393 assert!(mods.contains(KeyModifiers::SHIFT));
394 assert!(mods.contains(KeyModifiers::CONTROL));
395 assert!(!mods.contains(KeyModifiers::ALT));
396 assert!(!mods.is_empty());
397
398 let inverse = !mods;
399 assert!(inverse.contains(KeyModifiers::ALT));
400 assert!(inverse.contains(KeyModifiers::SUPER));
401 assert!(!inverse.contains(KeyModifiers::SHIFT));
402 assert!(!inverse.contains(KeyModifiers::CONTROL));
403 }
404
405 #[derive(Default)]
408 struct TestHasher(u64);
409
410 impl core::hash::Hasher for TestHasher {
411 fn finish(&self) -> u64 {
412 self.0
413 }
414 fn write(&mut self, bytes: &[u8]) {
415 for byte in bytes {
416 self.0 = self.0.wrapping_mul(31).wrapping_add(u64::from(*byte));
417 }
418 }
419 }
420
421 #[test]
422 fn test_key_modifiers_not_masks_unused_bits() {
423 use core::hash::Hash;
424
425 let all =
426 KeyModifiers::SHIFT | KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SUPER;
427 let inverse = !KeyModifiers::NONE;
428
429 assert_eq!(inverse, all, "NOT NONE should equal ALL");
432
433 let mut inverse_hasher = TestHasher::default();
434 inverse.hash(&mut inverse_hasher);
435 let mut all_hasher = TestHasher::default();
436 all.hash(&mut all_hasher);
437 assert_eq!(
438 core::hash::Hasher::finish(&inverse_hasher),
439 core::hash::Hasher::finish(&all_hasher),
440 "NOT NONE should hash the same as ALL"
441 );
442 }
443
444 #[test]
445 fn test_key_modifiers_super() {
446 let mods = KeyModifiers::SUPER;
447 assert!(mods.contains(KeyModifiers::SUPER));
448 assert!(!mods.contains(KeyModifiers::SHIFT));
449 assert!(!mods.contains(KeyModifiers::CONTROL));
450 assert!(!mods.contains(KeyModifiers::ALT));
451
452 let all =
453 KeyModifiers::SHIFT | KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SUPER;
454 assert!(all.contains(KeyModifiers::SUPER));
455 assert!(all.contains(KeyModifiers::SHIFT));
456 assert!(all.contains(KeyModifiers::CONTROL));
457 assert!(all.contains(KeyModifiers::ALT));
458 }
459
460 #[test]
461 fn test_key_modifiers_from_bits_truncate() {
462 assert_eq!(KeyModifiers::from_bits_truncate(0), KeyModifiers::NONE);
463 assert_eq!(KeyModifiers::from_bits_truncate(1), KeyModifiers::SHIFT);
464 assert_eq!(KeyModifiers::from_bits_truncate(2), KeyModifiers::CONTROL);
465 assert_eq!(KeyModifiers::from_bits_truncate(4), KeyModifiers::ALT);
466 assert_eq!(KeyModifiers::from_bits_truncate(8), KeyModifiers::SUPER);
467 assert_eq!(
468 KeyModifiers::from_bits_truncate(0b1111),
469 KeyModifiers::SHIFT | KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SUPER
470 );
471 assert_eq!(
473 KeyModifiers::from_bits_truncate(0xFF),
474 KeyModifiers::SHIFT | KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SUPER
475 );
476 }
477
478 #[test]
479 fn test_key_modifiers_bits_round_trip() {
480 for bits in 0..=u8::MAX {
481 assert_eq!(KeyModifiers::from_bits_truncate(bits).bits(), bits & 0b1111);
482 }
483 }
484
485 #[test]
486 fn test_key_modifiers_from_parts() {
487 assert_eq!(
488 KeyModifiers::from_parts(false, false, false, false),
489 KeyModifiers::NONE
490 );
491 assert_eq!(
492 KeyModifiers::from_parts(true, false, false, false),
493 KeyModifiers::SHIFT
494 );
495 assert_eq!(
496 KeyModifiers::from_parts(false, true, false, false),
497 KeyModifiers::CONTROL
498 );
499 assert_eq!(
500 KeyModifiers::from_parts(false, false, true, false),
501 KeyModifiers::ALT
502 );
503 assert_eq!(
504 KeyModifiers::from_parts(false, false, false, true),
505 KeyModifiers::SUPER
506 );
507 assert_eq!(
508 KeyModifiers::from_parts(true, true, true, true),
509 KeyModifiers::SHIFT | KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SUPER
510 );
511 }
512
513 #[test]
514 fn test_event_construction() {
515 let key_event = KeyEvent::new(KeyCode::Char('a'), KeyModifiers::SHIFT);
516 let event = Event::Key(key_event);
517
518 if let Event::Key(ke) = event {
519 assert_eq!(ke.code, KeyCode::Char('a'));
520 assert!(ke.modifiers.contains(KeyModifiers::SHIFT));
521 assert_eq!(ke.kind, KeyEventKind::Press);
522 } else {
523 panic!("Expected Event::Key");
524 }
525 }
526
527 #[test]
528 fn test_key_event_kind_helpers() {
529 let press = KeyEvent::new(KeyCode::Char('x'), KeyModifiers::NONE);
530 assert_eq!(press.kind, KeyEventKind::Press);
531 assert!(press.is_down());
532
533 let repeat =
534 KeyEvent::with_kind(KeyCode::Char('x'), KeyModifiers::NONE, KeyEventKind::Repeat);
535 assert!(repeat.is_down());
536
537 let release = KeyEvent::with_kind(
538 KeyCode::Char('x'),
539 KeyModifiers::NONE,
540 KeyEventKind::Release,
541 );
542 assert!(!release.is_down());
543 }
544
545 #[test]
546 fn test_key_state_tracks_held_keys() {
547 let mut state = KeyState::new();
548 assert!(!state.is_held(KeyCode::Left, KeyLocation::Standard));
549
550 state.apply(KeyEvent::new(KeyCode::Left, KeyModifiers::NONE));
551 assert!(state.is_held(KeyCode::Left, KeyLocation::Standard));
552
553 state.apply(KeyEvent::with_kind(
555 KeyCode::Left,
556 KeyModifiers::NONE,
557 KeyEventKind::Repeat,
558 ));
559 assert!(state.is_held(KeyCode::Left, KeyLocation::Standard));
560
561 state.apply(KeyEvent::with_kind(
562 KeyCode::Left,
563 KeyModifiers::NONE,
564 KeyEventKind::Release,
565 ));
566 assert!(!state.is_held(KeyCode::Left, KeyLocation::Standard));
567 }
568
569 #[test]
570 fn test_key_state_distinguishes_numpad_from_standard() {
571 let mut state = KeyState::new();
572 state.apply(KeyEvent::with_location(
573 KeyCode::Char('8'),
574 KeyModifiers::NONE,
575 KeyEventKind::Press,
576 KeyLocation::Numpad,
577 ));
578 assert!(state.is_held(KeyCode::Char('8'), KeyLocation::Numpad));
579 assert!(!state.is_held(KeyCode::Char('8'), KeyLocation::Standard));
580
581 state.apply(KeyEvent::new(KeyCode::Char('8'), KeyModifiers::NONE));
582 assert!(state.is_held(KeyCode::Char('8'), KeyLocation::Standard));
583 assert!(state.is_held(KeyCode::Char('8'), KeyLocation::Numpad));
584
585 state.apply(KeyEvent::with_kind(
586 KeyCode::Char('8'),
587 KeyModifiers::NONE,
588 KeyEventKind::Release,
589 ));
590 assert!(!state.is_held(KeyCode::Char('8'), KeyLocation::Standard));
591 assert!(state.is_held(KeyCode::Char('8'), KeyLocation::Numpad));
592 }
593
594 #[test]
595 fn test_key_state_apply_event_ignores_non_key() {
596 let mut state = KeyState::new();
597 state.apply_event(&Event::Resize(1, 1));
598 assert!(state.held().next().is_none());
599 state.apply_event(&Event::Key(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE)));
600 assert!(state.is_held(KeyCode::Up, KeyLocation::Standard));
601 }
602
603 #[test]
604 fn test_key_state_apply_event_clears_on_focus_lost() {
605 let mut state = KeyState::new();
606 state.apply_event(&Event::Key(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE)));
607 state.apply_event(&Event::Key(KeyEvent::new(
608 KeyCode::Left,
609 KeyModifiers::NONE,
610 )));
611 assert!(state.is_held(KeyCode::Up, KeyLocation::Standard));
612 assert!(state.is_held(KeyCode::Left, KeyLocation::Standard));
613
614 state.apply_event(&Event::FocusLost);
618 assert!(!state.is_held(KeyCode::Up, KeyLocation::Standard));
619 assert!(!state.is_held(KeyCode::Left, KeyLocation::Standard));
620 assert!(state.held().next().is_none());
621 }
622
623 #[test]
624 fn test_key_state_clear() {
625 let mut state = KeyState::new();
626 state.apply(KeyEvent::new(KeyCode::Left, KeyModifiers::NONE));
627 state.apply(KeyEvent::new(KeyCode::Right, KeyModifiers::NONE));
628 assert_eq!(state.held().count(), 2);
629
630 state.clear();
631 assert!(state.held().next().is_none());
632 assert!(!state.is_held(KeyCode::Left, KeyLocation::Standard));
633 assert!(!state.is_held(KeyCode::Right, KeyLocation::Standard));
634
635 state.clear();
637 assert!(state.held().next().is_none());
638 }
639
640 #[test]
641 fn test_key_state_held_is_in_first_pressed_order() {
642 let mut state = KeyState::new();
643 state.apply(KeyEvent::new(KeyCode::Left, KeyModifiers::NONE));
644 state.apply(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE));
645 state.apply(KeyEvent::new(KeyCode::Right, KeyModifiers::NONE));
646 assert_eq!(
647 state.held().collect::<Vec<_>>(),
648 vec![
649 (KeyCode::Left, KeyLocation::Standard),
650 (KeyCode::Up, KeyLocation::Standard),
651 (KeyCode::Right, KeyLocation::Standard),
652 ]
653 );
654
655 state.apply(KeyEvent::with_kind(
658 KeyCode::Left,
659 KeyModifiers::NONE,
660 KeyEventKind::Release,
661 ));
662 state.apply(KeyEvent::new(KeyCode::Left, KeyModifiers::NONE));
663 assert_eq!(
664 state.held().collect::<Vec<_>>(),
665 vec![
666 (KeyCode::Up, KeyLocation::Standard),
667 (KeyCode::Right, KeyLocation::Standard),
668 (KeyCode::Left, KeyLocation::Standard),
669 ]
670 );
671 }
672
673 #[test]
674 fn test_key_state_release_of_unpressed_key_is_a_no_op() {
675 let mut state = KeyState::new();
676 state.apply(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE));
677
678 state.apply(KeyEvent::with_kind(
680 KeyCode::Down,
681 KeyModifiers::NONE,
682 KeyEventKind::Release,
683 ));
684 assert!(!state.is_held(KeyCode::Down, KeyLocation::Standard));
685 assert!(state.is_held(KeyCode::Up, KeyLocation::Standard));
686 assert_eq!(state.held().count(), 1);
687 }
688
689 #[cfg(feature = "serde")]
690 #[test]
691 fn key_event_and_key_state_round_trip_through_serde_json() {
692 let event = KeyEvent::with_location(
693 KeyCode::Modifier(ModifierKey::Shift),
694 KeyModifiers::SHIFT | KeyModifiers::ALT,
695 KeyEventKind::Repeat,
696 KeyLocation::Left,
697 );
698 let json = serde_json::to_string(&event).expect("serialize");
699 assert_eq!(
700 serde_json::from_str::<KeyEvent>(&json).expect("deserialize"),
701 event
702 );
703
704 let mut state = KeyState::new();
705 state.apply(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE));
706 let json = serde_json::to_string(&state).expect("serialize");
707 assert_eq!(
708 serde_json::from_str::<KeyState>(&json)
709 .expect("deserialize")
710 .held()
711 .collect::<Vec<_>>(),
712 state.held().collect::<Vec<_>>()
713 );
714 }
715
716 #[test]
717 fn test_key_state_double_press_without_release_does_not_duplicate() {
718 let mut state = KeyState::new();
719 state.apply(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE));
720 state.apply(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE));
721 assert_eq!(state.held().count(), 1);
722
723 state.apply(KeyEvent::with_kind(
726 KeyCode::Up,
727 KeyModifiers::NONE,
728 KeyEventKind::Release,
729 ));
730 assert!(!state.is_held(KeyCode::Up, KeyLocation::Standard));
731 assert!(state.held().next().is_none());
732 }
733}