Skip to main content

qmk_via_api/
scan.rs

1use crate::Result;
2use hidapi::HidApi;
3
4#[cfg(feature = "python")]
5use pyo3::prelude::*;
6
7const VIA_USAGE_PAGE: u16 = 0xff60;
8
9/// Information about a connected VIA-compatible keyboard.
10#[cfg_attr(feature = "python", pyclass(get_all, from_py_object))]
11#[derive(Clone, Debug)]
12pub struct KeyboardDeviceInfo {
13    /// USB vendor ID
14    pub vendor_id: u16,
15    /// USB product ID
16    pub product_id: u16,
17    /// HID usage page (expected to be 0xFF60 for VIA)
18    pub usage_page: u16,
19    /// Optional manufacturer string
20    pub manufacturer: Option<String>,
21    /// Optional product string
22    pub product: Option<String>,
23    /// Optional serial number string
24    pub serial_number: Option<String>,
25}
26
27/// Scan for connected VIA keyboards.
28#[cfg_attr(feature = "python", pyfunction)]
29pub fn scan_keyboards() -> Result<Vec<KeyboardDeviceInfo>> {
30    let api = HidApi::new()?;
31
32    Ok(api
33        .device_list()
34        .filter(|d| d.usage_page() == VIA_USAGE_PAGE)
35        .map(|d| KeyboardDeviceInfo {
36            vendor_id: d.vendor_id(),
37            product_id: d.product_id(),
38            usage_page: d.usage_page(),
39            manufacturer: d.manufacturer_string().map(|s| s.to_string()),
40            product: d.product_string().map(|s| s.to_string()),
41            serial_number: d.serial_number().map(|s| s.to_string()),
42        })
43        .collect())
44}