clicker 0.4.1

a simple desktop automation tool
mod parse;

use device_query::*;
use enigo::{Enigo, MouseButton, MouseControllable};
use log::info;
use parse::{parse_keycode, parse_mousebutton};
use rand::Rng;
use std::{thread, time};
use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(name = "clicker", about = "a simple desktop automation tool")]
struct Opt {
    /// The time in milliseconds that will be waited between clicks
    #[structopt(short, long, default_value = "70")]
    delay: u64,
    /// The time in milliseconds that will spent between the mouse down and the mouse up event
    #[structopt(short, long, default_value = "5")]
    click_time: u64,
    /// The keycode that is needed to be pressed for clicks to be made
    #[structopt(short, long, parse(try_from_str = "parse_keycode"))]
    key: Option<Keycode>,
    /// The mouse button that will be press
    #[structopt(
        short,
        long,
        default_value = "Left",
        parse(try_from_str = "parse_mousebutton")
    )]
    button: MouseButton,
    /// The time range in milliseconds that will randomly be different between each mouseclick
    #[structopt(short, long)]
    random: Option<u64>,
}

fn main() {
    env_logger::init();
    let opt = Opt::from_args();
    let mut enigo = Enigo::new();
    let device_state = DeviceState::new();
    let mut rng = rand::thread_rng();
    loop {
        let keys = device_state.get_keys();
        if opt.key.as_ref().map_or(true, |key| keys.contains(&key)) {
            click(&mut enigo, opt.button, opt.click_time);
        }
        let sleep_time = if let Some(random) = opt.random {
            opt.delay + rng.gen_range(0, random + 1) - (random / 2)
        } else {
            opt.delay
        };
        thread::sleep(time::Duration::from_millis(sleep_time));
    }
}

fn click(enigo: &mut Enigo, button: MouseButton, time: u64) {
    enigo.mouse_down(button);
    thread::sleep(time::Duration::from_millis(time));
    enigo.mouse_up(button);
    info!("Clicked mouse button");
}