br-hid 0.2.1

This is an Bluetooth HID
Documentation
use std::{
    sync::{
        mpsc::{self, channel, Sender},
        Arc, Mutex, RwLock
    },
    thread
};
use std::time::Duration;
use std::collections::HashMap;

use hidapi::HidApi;
use windows::Win32::UI::Input::*;

use json::JsonValue;
use lazy_static::lazy_static;

mod raw_input_api;
use raw_input_api::*;

use crate::{Device, Handler, Types};

lazy_static! {
    // #[allow(clippy::type_complexity)]
    static ref LISTEN_DEVICE_VEC :Arc<Mutex<HashMap<isize, Sender<(RAWKEYBOARD, bool)>>>> = Arc::new(Mutex::new(HashMap::new()));
    static ref CONNECT_DEVICE_VEC:Arc<RwLock<Vec<String>>> = Arc::new(RwLock::new(Vec::new()));
}


#[derive(Clone)]
pub struct Win { }
impl Default for Win {
    fn default() -> Self {
        Self::new()
    }
}

impl Win {
    pub fn new() -> Self {
        log::debug!("New win instance");
        Self {}
    }

    pub fn run<F>(&self, factory: F)
    where
        F: FnOnce() -> Box<dyn Handler>,
    {
        start_raw_input_task();

        let mut buf = vec![];
        // scan devices
        log::debug!("hidapi scan loop");
        let mut handler = factory(); // ✅ 只调用一次

        loop {
            let hidapi = match HidApi::new() {
                Ok(v) => v,
                Err(e) => {
                    log::warn!("HidApi::new() failed: {:?}", e);
                    continue;
                }
            };

            log::trace!("Iterator hidapi device list");
            let mut recent_device_vec = vec![];

            for device in hidapi.device_list() {
                let usage = device.usage();
                let usage_page = device.usage_page();

                // not hid keyboard
                if usage != 6 || usage_page != 1 {
                    continue;
                }

                let uid = get_uid_from_device_info(&device);

                recent_device_vec.push(uid.clone());

               if !buf.contains(&uid) {
                    let raw_path = device.path().to_string_lossy().to_string();
                    log::debug!(
                        "Found device prod: {}, {}\nraw_path: {}, uid: {}",
                        device.product_string().unwrap(),
                        device.manufacturer_string().unwrap(),
                        raw_path,
                        uid,
                    );
                    buf.push(uid.clone());
                }

                let r = Device {
                    id: uid,
                    vid: device.vendor_id().to_string(),
                    pid: device.product_id().to_string(),
                    types: Types::Keyboard,
                    manufacturer: device.manufacturer_string().unwrap().trim().to_string(),
                    name: device.product_string().unwrap().trim().to_string(),
                    value: JsonValue::from("".to_string()),
                    count: 0,
                };
                handler.on_discover(r);
            }

            {
                // update connect device list
                let r = CONNECT_DEVICE_VEC.read().unwrap();
                if *r != recent_device_vec {
                    drop(r);
                    log::debug!("Update CONNECT_DEVICE_VEC");

                    let mut w = CONNECT_DEVICE_VEC.write().unwrap();
                    w.drain(..);
                    w.extend(recent_device_vec);
                    drop(w);
                }
            }

            thread::sleep(Duration::from_secs(3));
        }
    }

    pub fn connect<F>(&self, id: String, factory: F)
    where
        F: FnOnce() -> Box<dyn Handler>,
    {
        let device_handle_0 = match get_device_handle_0(&id){
            Some(v) => v,
            None => {
                log::info!("Connect reqeust device not found: {}", id);
                factory().on_disconnected(id, "未找到设备".to_string());
                return;
            }
        };

        let (tx, rx) = channel();

        // register detect device
        log::info!("Register detect device: h: {}, id: {}", device_handle_0, id);
        let mut w = LISTEN_DEVICE_VEC.lock().unwrap();
        w.insert(device_handle_0, tx);
        let mut handler = factory(); // ✅ 只调用一次

        drop(w);

        handler.on_connect(id.clone());

        let mut cache = String::with_capacity(32);
        loop {
            match rx.recv_timeout(Duration::from_millis(1000)) {
                Ok(raw_keyboard) => {
                    let digit_str = raw_keyboard_to_digit_str(raw_keyboard.0, raw_keyboard.1);
                    log::trace!("Recv raw input str: id: {}, digit: {}", id, digit_str);
                    if digit_str == "\n" || digit_str == "\t" {
                        if !cache.is_empty() {
                            handler.on_data(id.clone(), cache.clone().into());
                        }
                        cache.clear();
                    } else {
                        cache = format!("{cache}{}", digit_str);
                    }
                },
                Err(mpsc::RecvTimeoutError::Timeout) => {
                    if handler.on_is_close(id.clone()) {
                        log::debug!("on_is_close");
                        handler.on_disconnected(id.clone(), "软件主动断开连接".to_string());
                        break;
                    }

                    // log::debug!("check CONNECT_DEVICE_VEC");
                    let r = CONNECT_DEVICE_VEC.read().unwrap();
                    if !r.contains(&id){
                        log::debug!("Device not found in device list");
                        handler.on_disconnected(id.clone(), "设备已从连接列表中消失".to_string());
                        drop(r);
                        break;
                    }
                },
                Err(mpsc::RecvTimeoutError::Disconnected) => {
                    log::warn!("Channel disconnect");
                    handler.on_disconnected(id.clone(), "设备已断开".to_string());
                    break;
                },
            }
        }

        log::debug!("Connect message loop out: {} {}", device_handle_0, id);
        let mut w = LISTEN_DEVICE_VEC.lock().unwrap();
        w.remove(&device_handle_0);
        drop(w);
    }
}