tauri_plugin_prevent_default/shortcut/
mod.rs

1mod keyboard;
2mod pointer;
3
4use std::fmt;
5use strum::{Display, EnumIs};
6
7pub use keyboard::{KeyboardShortcut, KeyboardShortcutBuilder};
8pub use pointer::{PointerEvent, PointerShortcut, PointerShortcutBuilder};
9
10pub trait Shortcut: fmt::Display {
11  fn kind(&self) -> ShortcutKind<'_>;
12}
13
14impl Shortcut for KeyboardShortcut {
15  fn kind(&self) -> ShortcutKind<'_> {
16    ShortcutKind::Keyboard(self)
17  }
18}
19
20impl Shortcut for PointerShortcut {
21  fn kind(&self) -> ShortcutKind<'_> {
22    ShortcutKind::Pointer(self)
23  }
24}
25
26#[derive(Debug)]
27pub enum ShortcutKind<'a> {
28  Keyboard(&'a KeyboardShortcut),
29  Pointer(&'a PointerShortcut),
30}
31
32impl ShortcutKind<'_> {
33  /// Returns `true` if the shortcut is a keyboard shortcut.
34  pub fn is_keyboard(&self) -> bool {
35    matches!(self, ShortcutKind::Keyboard(_))
36  }
37
38  /// Returns `true` if the shortcut is a pointer shortcut.
39  pub fn is_pointer(&self) -> bool {
40    matches!(self, ShortcutKind::Pointer(_))
41  }
42}
43
44#[non_exhaustive]
45#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, Hash, EnumIs)]
46#[strum(serialize_all = "camelCase")]
47pub enum ModifierKey {
48  AltKey,
49  CtrlKey,
50  MetaKey,
51  ShiftKey,
52}
53
54impl ModifierKey {
55  fn precedence(self) -> u8 {
56    match self {
57      ModifierKey::CtrlKey => 0,
58      ModifierKey::ShiftKey => 1,
59      ModifierKey::AltKey => 2,
60      ModifierKey::MetaKey => 3,
61    }
62  }
63}
64
65impl PartialOrd for ModifierKey {
66  fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
67    Some(self.cmp(other))
68  }
69}
70
71impl Ord for ModifierKey {
72  fn cmp(&self, other: &Self) -> std::cmp::Ordering {
73    self.precedence().cmp(&other.precedence())
74  }
75}
76
77#[cfg(test)]
78mod test {
79  use super::ModifierKey::{AltKey, CtrlKey, MetaKey, ShiftKey};
80  use super::*;
81
82  #[test]
83  fn shortcut_kind() {
84    // Keyboard
85    let keyboard = KeyboardShortcut::new("F12");
86    let keyboard = Box::new(keyboard) as Box<dyn Shortcut>;
87    assert!(keyboard.kind().is_keyboard());
88
89    // Pointer
90    let pointer = PointerShortcut::new(PointerEvent::ContextMenu);
91    let pointer = Box::new(pointer) as Box<dyn Shortcut>;
92    assert!(pointer.kind().is_pointer());
93  }
94
95  #[test]
96  fn modifier_key_order() {
97    assert!(CtrlKey < ShiftKey);
98    assert!(ShiftKey < AltKey);
99    assert!(CtrlKey < AltKey);
100
101    let mut modifiers = vec![AltKey, MetaKey, CtrlKey, ShiftKey];
102    modifiers.sort();
103
104    assert_eq!(modifiers, vec![CtrlKey, ShiftKey, AltKey, MetaKey]);
105  }
106}