use itertools::{join, Itertools};
use std::convert::TryFrom;
use std::fmt::{Display, Error, Formatter};
pub trait Keyboard {
fn press(&self, key: KeyboardKey) -> bool;
fn press_all(&self, keys: KeyboardKeys) -> Vec<bool> {
keys.0.into_iter().map(|k| self.press(k)).collect_vec()
}
fn release(&self, key: KeyboardKey) -> bool;
fn release_all(&self, keys: KeyboardKeys) -> Vec<bool> {
keys.0.into_iter().map(|k| self.release(k)).collect_vec()
}
fn is_pressed(&self, key: KeyboardKey) -> bool;
fn is_pressed_all(&self, keys: KeyboardKeys) -> Vec<bool> {
keys.0.into_iter().map(|k| self.is_pressed(k)).collect_vec()
}
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum KeyboardKey {
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
Num1,
Num2,
Num3,
Num4,
Num5,
Num6,
Num7,
Num8,
Num9,
Num0,
Enter,
Esc,
Del,
Tab,
Space,
LeftControl,
LeftShift,
LeftAlt,
LeftWindows,
RightControl,
RightShift,
RightAlt,
RightWindows,
}
impl TryFrom<&str> for KeyboardKey {
type Error = &'static str;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value.to_lowercase().as_str() {
"a" => Ok(KeyboardKey::A),
"b" => Ok(KeyboardKey::B),
"c" => Ok(KeyboardKey::C),
"d" => Ok(KeyboardKey::D),
"e" => Ok(KeyboardKey::E),
"f" => Ok(KeyboardKey::F),
"g" => Ok(KeyboardKey::G),
"h" => Ok(KeyboardKey::H),
"i" => Ok(KeyboardKey::I),
"j" => Ok(KeyboardKey::J),
"k" => Ok(KeyboardKey::K),
"l" => Ok(KeyboardKey::L),
"m" => Ok(KeyboardKey::M),
"n" => Ok(KeyboardKey::N),
"o" => Ok(KeyboardKey::O),
"p" => Ok(KeyboardKey::P),
"q" => Ok(KeyboardKey::Q),
"r" => Ok(KeyboardKey::R),
"s" => Ok(KeyboardKey::S),
"t" => Ok(KeyboardKey::T),
"u" => Ok(KeyboardKey::U),
"v" => Ok(KeyboardKey::V),
"w" => Ok(KeyboardKey::W),
"x" => Ok(KeyboardKey::X),
"y" => Ok(KeyboardKey::Y),
"z" => Ok(KeyboardKey::Z),
"1" => Ok(KeyboardKey::Num1),
"2" => Ok(KeyboardKey::Num2),
"3" => Ok(KeyboardKey::Num3),
"4" => Ok(KeyboardKey::Num4),
"5" => Ok(KeyboardKey::Num5),
"6" => Ok(KeyboardKey::Num6),
"7" => Ok(KeyboardKey::Num7),
"8" => Ok(KeyboardKey::Num8),
"9" => Ok(KeyboardKey::Num9),
"0" => Ok(KeyboardKey::Num0),
"enter" => Ok(KeyboardKey::Enter),
"esc" => Ok(KeyboardKey::Esc),
"del" => Ok(KeyboardKey::Del),
"tab" => Ok(KeyboardKey::Tab),
"space" => Ok(KeyboardKey::Space),
"left-ctrl" => Ok(KeyboardKey::LeftControl),
"left-shift" => Ok(KeyboardKey::LeftShift),
"left-alt" => Ok(KeyboardKey::LeftAlt),
"left-win" => Ok(KeyboardKey::LeftWindows),
"right-ctrl" => Ok(KeyboardKey::RightControl),
"right-shift" => Ok(KeyboardKey::RightShift),
"right-alt" => Ok(KeyboardKey::RightAlt),
"right-win" => Ok(KeyboardKey::RightWindows),
v if v.is_empty() => Err("Input is empty"),
_ => Err("Invalid input"),
}
}
}
impl Display for KeyboardKey {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
let value = match self {
KeyboardKey::A => "a",
KeyboardKey::B => "b",
KeyboardKey::C => "c",
KeyboardKey::D => "d",
KeyboardKey::E => "e",
KeyboardKey::F => "f",
KeyboardKey::G => "g",
KeyboardKey::H => "h",
KeyboardKey::I => "i",
KeyboardKey::J => "j",
KeyboardKey::K => "k",
KeyboardKey::L => "l",
KeyboardKey::M => "m",
KeyboardKey::N => "n",
KeyboardKey::O => "o",
KeyboardKey::P => "p",
KeyboardKey::Q => "q",
KeyboardKey::R => "r",
KeyboardKey::S => "s",
KeyboardKey::T => "t",
KeyboardKey::U => "u",
KeyboardKey::V => "v",
KeyboardKey::W => "w",
KeyboardKey::X => "x",
KeyboardKey::Y => "y",
KeyboardKey::Z => "z",
KeyboardKey::Num1 => "1",
KeyboardKey::Num2 => "2",
KeyboardKey::Num3 => "3",
KeyboardKey::Num4 => "4",
KeyboardKey::Num5 => "5",
KeyboardKey::Num6 => "6",
KeyboardKey::Num7 => "7",
KeyboardKey::Num8 => "8",
KeyboardKey::Num9 => "9",
KeyboardKey::Num0 => "0",
KeyboardKey::Enter => "enter",
KeyboardKey::Esc => "esc",
KeyboardKey::Del => "del",
KeyboardKey::Tab => "tab",
KeyboardKey::Space => "space",
KeyboardKey::LeftControl => "left-ctrl",
KeyboardKey::LeftShift => "left-shift",
KeyboardKey::LeftAlt => "left-alt",
KeyboardKey::LeftWindows => "left-win",
KeyboardKey::RightControl => "right-ctrl",
KeyboardKey::RightShift => "right-shift",
KeyboardKey::RightAlt => "right-alt",
KeyboardKey::RightWindows => "right-win",
};
write!(f, "{}", value)
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct KeyboardKeys(pub(crate) Vec<KeyboardKey>);
impl KeyboardKeys {
pub fn new() -> Self {
KeyboardKeys(vec![])
}
pub fn add_key(mut self, key: KeyboardKey) -> Self {
self.0.push(key);
self
}
}
impl Display for KeyboardKeys {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
let keys_string: Vec<String> = self.0.iter().map(|k| k.to_string()).collect();
write!(f, "{}", join(&keys_string, "+"))
}
}
impl TryFrom<&str> for KeyboardKeys {
type Error = &'static str;
fn try_from(value: &str) -> Result<Self, Self::Error> {
if value.is_empty() {
return Err("Input is empty");
}
let split: Vec<&str> = value.split("+").collect();
let mut keys = vec![];
for arg in split {
match KeyboardKey::try_from(arg) {
Ok(key) => keys.push(key),
Err(_) => return Err("Invalid input"),
}
}
Ok(KeyboardKeys(keys))
}
}