virtual-input 0.2.8

API for interacting with virtual input devices
Documentation
use itertools::{join, Itertools};
use std::convert::TryFrom;
use std::fmt::{Display, Error, Formatter};
use strum_macros::EnumIter;

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, EnumIter)]
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))
    }
}