1use itertools::{join, Itertools};
2use std::convert::TryFrom;
3use std::fmt::{Display, Error, Formatter};
4use strum_macros::EnumIter;
5
6pub trait Keyboard {
7 fn press(&self, key: KeyboardKey) -> bool;
8
9 fn press_all(&self, keys: KeyboardKeys) -> Vec<bool> {
10 keys.0.into_iter().map(|k| self.press(k)).collect_vec()
11 }
12
13 fn release(&self, key: KeyboardKey) -> bool;
14
15 fn release_all(&self, keys: KeyboardKeys) -> Vec<bool> {
16 keys.0.into_iter().map(|k| self.release(k)).collect_vec()
17 }
18
19 fn is_pressed(&self, key: KeyboardKey) -> bool;
20
21 fn is_pressed_all(&self, keys: KeyboardKeys) -> Vec<bool> {
22 keys.0.into_iter().map(|k| self.is_pressed(k)).collect_vec()
23 }
24}
25
26#[derive(Debug, Eq, PartialEq, Copy, Clone, EnumIter)]
27pub enum KeyboardKey {
28 A,
29 B,
30 C,
31 D,
32 E,
33 F,
34 G,
35 H,
36 I,
37 J,
38 K,
39 L,
40 M,
41 N,
42 O,
43 P,
44 Q,
45 R,
46 S,
47 T,
48 U,
49 V,
50 W,
51 X,
52 Y,
53 Z,
54 Num1,
55 Num2,
56 Num3,
57 Num4,
58 Num5,
59 Num6,
60 Num7,
61 Num8,
62 Num9,
63 Num0,
64 Enter,
65 Esc,
66 Del,
67 Tab,
68 Space,
69 LeftControl,
70 LeftShift,
71 LeftAlt,
72 LeftWindows,
73 RightControl,
74 RightShift,
75 RightAlt,
76 RightWindows,
77}
78
79impl TryFrom<&str> for KeyboardKey {
80 type Error = &'static str;
81
82 fn try_from(value: &str) -> Result<Self, Self::Error> {
83 match value.to_lowercase().as_str() {
84 "a" => Ok(KeyboardKey::A),
85 "b" => Ok(KeyboardKey::B),
86 "c" => Ok(KeyboardKey::C),
87 "d" => Ok(KeyboardKey::D),
88 "e" => Ok(KeyboardKey::E),
89 "f" => Ok(KeyboardKey::F),
90 "g" => Ok(KeyboardKey::G),
91 "h" => Ok(KeyboardKey::H),
92 "i" => Ok(KeyboardKey::I),
93 "j" => Ok(KeyboardKey::J),
94 "k" => Ok(KeyboardKey::K),
95 "l" => Ok(KeyboardKey::L),
96 "m" => Ok(KeyboardKey::M),
97 "n" => Ok(KeyboardKey::N),
98 "o" => Ok(KeyboardKey::O),
99 "p" => Ok(KeyboardKey::P),
100 "q" => Ok(KeyboardKey::Q),
101 "r" => Ok(KeyboardKey::R),
102 "s" => Ok(KeyboardKey::S),
103 "t" => Ok(KeyboardKey::T),
104 "u" => Ok(KeyboardKey::U),
105 "v" => Ok(KeyboardKey::V),
106 "w" => Ok(KeyboardKey::W),
107 "x" => Ok(KeyboardKey::X),
108 "y" => Ok(KeyboardKey::Y),
109 "z" => Ok(KeyboardKey::Z),
110 "1" => Ok(KeyboardKey::Num1),
111 "2" => Ok(KeyboardKey::Num2),
112 "3" => Ok(KeyboardKey::Num3),
113 "4" => Ok(KeyboardKey::Num4),
114 "5" => Ok(KeyboardKey::Num5),
115 "6" => Ok(KeyboardKey::Num6),
116 "7" => Ok(KeyboardKey::Num7),
117 "8" => Ok(KeyboardKey::Num8),
118 "9" => Ok(KeyboardKey::Num9),
119 "0" => Ok(KeyboardKey::Num0),
120 "enter" => Ok(KeyboardKey::Enter),
121 "esc" => Ok(KeyboardKey::Esc),
122 "del" => Ok(KeyboardKey::Del),
123 "tab" => Ok(KeyboardKey::Tab),
124 "space" => Ok(KeyboardKey::Space),
125 "left-ctrl" => Ok(KeyboardKey::LeftControl),
126 "left-shift" => Ok(KeyboardKey::LeftShift),
127 "left-alt" => Ok(KeyboardKey::LeftAlt),
128 "left-win" => Ok(KeyboardKey::LeftWindows),
129 "right-ctrl" => Ok(KeyboardKey::RightControl),
130 "right-shift" => Ok(KeyboardKey::RightShift),
131 "right-alt" => Ok(KeyboardKey::RightAlt),
132 "right-win" => Ok(KeyboardKey::RightWindows),
133 v if v.is_empty() => Err("Input is empty"),
134 _ => Err("Invalid input"),
135 }
136 }
137}
138
139impl Display for KeyboardKey {
140 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
141 let value = match self {
142 KeyboardKey::A => "a",
143 KeyboardKey::B => "b",
144 KeyboardKey::C => "c",
145 KeyboardKey::D => "d",
146 KeyboardKey::E => "e",
147 KeyboardKey::F => "f",
148 KeyboardKey::G => "g",
149 KeyboardKey::H => "h",
150 KeyboardKey::I => "i",
151 KeyboardKey::J => "j",
152 KeyboardKey::K => "k",
153 KeyboardKey::L => "l",
154 KeyboardKey::M => "m",
155 KeyboardKey::N => "n",
156 KeyboardKey::O => "o",
157 KeyboardKey::P => "p",
158 KeyboardKey::Q => "q",
159 KeyboardKey::R => "r",
160 KeyboardKey::S => "s",
161 KeyboardKey::T => "t",
162 KeyboardKey::U => "u",
163 KeyboardKey::V => "v",
164 KeyboardKey::W => "w",
165 KeyboardKey::X => "x",
166 KeyboardKey::Y => "y",
167 KeyboardKey::Z => "z",
168 KeyboardKey::Num1 => "1",
169 KeyboardKey::Num2 => "2",
170 KeyboardKey::Num3 => "3",
171 KeyboardKey::Num4 => "4",
172 KeyboardKey::Num5 => "5",
173 KeyboardKey::Num6 => "6",
174 KeyboardKey::Num7 => "7",
175 KeyboardKey::Num8 => "8",
176 KeyboardKey::Num9 => "9",
177 KeyboardKey::Num0 => "0",
178 KeyboardKey::Enter => "enter",
179 KeyboardKey::Esc => "esc",
180 KeyboardKey::Del => "del",
181 KeyboardKey::Tab => "tab",
182 KeyboardKey::Space => "space",
183 KeyboardKey::LeftControl => "left-ctrl",
184 KeyboardKey::LeftShift => "left-shift",
185 KeyboardKey::LeftAlt => "left-alt",
186 KeyboardKey::LeftWindows => "left-win",
187 KeyboardKey::RightControl => "right-ctrl",
188 KeyboardKey::RightShift => "right-shift",
189 KeyboardKey::RightAlt => "right-alt",
190 KeyboardKey::RightWindows => "right-win",
191 };
192
193 write!(f, "{}", value)
194 }
195}
196
197#[derive(Debug, Eq, PartialEq, Clone)]
198pub struct KeyboardKeys(pub(crate) Vec<KeyboardKey>);
199
200impl KeyboardKeys {
201 pub fn new() -> Self {
202 KeyboardKeys(vec![])
203 }
204
205 pub fn add_key(mut self, key: KeyboardKey) -> Self {
206 self.0.push(key);
207 self
208 }
209}
210
211impl Display for KeyboardKeys {
212 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
213 let keys_string: Vec<String> = self.0.iter().map(|k| k.to_string()).collect();
214
215 write!(f, "{}", join(&keys_string, "+"))
216 }
217}
218
219impl TryFrom<&str> for KeyboardKeys {
220 type Error = &'static str;
221
222 fn try_from(value: &str) -> Result<Self, Self::Error> {
223 if value.is_empty() {
224 return Err("Input is empty");
225 }
226
227 let split: Vec<&str> = value.split("+").collect();
228 let mut keys = vec![];
229
230 for arg in split {
231 match KeyboardKey::try_from(arg) {
232 Ok(key) => keys.push(key),
233 Err(_) => return Err("Invalid input"),
234 }
235 }
236
237 Ok(KeyboardKeys(keys))
238 }
239}