vitaly 0.1.32

VIA/Vial API client and cli tool for guiless keyboard configuration.
Documentation
use crate::common;
use crate::keymap;
use crate::protocol;
use anyhow::{Result, anyhow};
use hidapi::{DeviceInfo, HidApi};
use std::{thread, time};

pub fn run(api: &HidApi, device: &DeviceInfo, meta_file: &Option<String>) -> Result<()> {
    let device_path = device.path();
    let dev = api.open_path(device_path)?;

    let capabilities = protocol::scan_capabilities(&dev)?;
    let meta = common::load_meta(&dev, &capabilities, meta_file)?;
    let cols = meta["matrix"]["cols"]
        .as_u64()
        .ok_or(anyhow!("matrix/cols not found in meta"))? as u8;
    let rows = meta["matrix"]["rows"]
        .as_u64()
        .ok_or(anyhow!("matrix/rows not found in meta"))? as u8;

    let state = protocol::load_layout_options(&dev)?;
    let options = protocol::LayoutOptions::from_json(state, &meta["layouts"]["labels"])?;
    let mut buttons = keymap::keymap_to_buttons(&meta["layouts"]["keymap"], &options)?;

    let sleep_duration = time::Duration::from_millis(50);
    let mut last_state: Option<protocol::MatrixState> = None;
    for button in &mut buttons {
        button.color = None;
    }
    if capabilities.vial_version > 0 {
        let status = protocol::get_locked_status(&dev)?;
        if status.locked {
            return Err(common::CommandError("Keyboard is locked, it's necessary to unlock it to run tester, keyboard might be unlocked with subcommand 'lock -u'".to_string()).into());
        }
    }
    println!("Tap buttons. Press Ctrl+c to finish.");
    keymap::render_and_dump(&buttons, None);

    loop {
        let state = protocol::matrix_poll(&dev, rows, cols)?;
        if let Some(last_state) = last_state
            && state != last_state
        {
            for button in &mut buttons {
                if state.is_pushed(button.wire_x, button.wire_y, capabilities.via_version)? {
                    button.color = Some((255, 255, 255));
                } else if button.color.is_some() {
                    button.color = Some((150, 150, 150));
                }
            }
            println!();
            keymap::render_and_dump(&buttons, None);
        }
        last_state = Some(state);
        thread::sleep(sleep_duration);
    }
}