1#[cfg(feature = "crossterm")]
2mod crossterm;
3
4#[cfg(feature = "termion")]
5mod termion;
6
7#[cfg(feature = "termwiz")]
8mod termwiz;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct Input {
12 pub key: Key,
13 pub modifier: Modifier,
14}
15
16impl Input {
17 pub fn new(key: Key, modifier: Modifier) -> Input {
18 Input { key, modifier }
19 }
20 pub fn new_key(key: Key) -> Input {
21 Input {
22 key,
23 modifier: Modifier::None,
24 }
25 }
26 pub fn keys(keys: &[Key]) -> Vec<Input> {
27 keys.iter().map(|key| Self::new_key(*key)).collect()
28 }
29 pub fn with_key(&mut self, key: Key) -> &mut Self {
30 self.key = key;
31 self
32 }
33 pub fn with_modifier(&mut self, modifier: Modifier) -> &mut Self {
34 self.modifier = modifier;
35 self
36 }
37}
38
39impl Default for Input {
40 fn default() -> Self {
41 Self {
42 key: Key::None,
43 modifier: Modifier::None,
44 }
45 }
46}
47
48#[derive(Debug, Clone, Copy, Eq)]
50pub enum Key {
51 Up,
52 Down,
53 Left,
54 Right,
55 Char(char),
58 Esc,
59 Backspace,
60 Enter,
61 Tab,
62 CapsLock,
63 Home,
65 End,
66 PageUp,
67 PageDown,
68 Delete,
69 Insert,
70 Func(u8),
72 ScrollLock,
73 NumLock,
74 PrintScreen,
75 Pause,
76 Menu,
77 BackTab,
78 MediaPlay,
80 MediaPause,
81 MediaPlayPause,
82 MediaStop,
83 MediaNext,
84 MediaPrevious,
85 RaisVolume,
86 LowerVolume,
87 MuteVolume,
88 Modifier(Modifier),
90 Any,
93 None,
96}
97
98macro_rules! really_match {
99 ($($kind:ident),+) => {
100 fn eq(&self, other: &Self) -> bool {
101 match self {
102 Self::Any => true,
103 $(Self::$kind(a) => {
104 if let Self::$kind(b) = other {
105 a == b
106 } else {
107 matches!(other, Self::Any)
108 }
109 })+
110 _ => match other {
111 Self::Any => true,
112 _ => core::mem::discriminant(self) == core::mem::discriminant(other),
113 },
114 }
115 }
116 };
117}
118
119impl PartialEq for Key {
120 really_match!(Char, Func, Modifier);
121}
122
123#[derive(Debug, Clone, Copy, Eq)]
124pub enum Modifier {
125 Shift(Side),
126 Control(Side),
127 Alt(Side),
128 Super(Side),
130 Meta(Side),
131 Hyper(Side),
132 Any,
135 None,
137}
138impl PartialEq for Modifier {
139 really_match!(Shift, Control, Alt, Super, Meta, Hyper);
140}
141
142#[derive(Debug, Clone, Copy, Eq)]
143pub enum Side {
145 Left,
146 Right,
147 Any,
150}
151
152impl PartialEq for Side {
153 fn eq(&self, other: &Self) -> bool {
154 match self {
155 Self::Any => true,
156 _ => match other {
157 Self::Any => true,
158 _ => core::mem::discriminant(self) == core::mem::discriminant(other),
159 },
160 }
161 }
162}