1use crate::Result;
2use hidapi::HidApi;
3
4#[cfg(feature = "python")]
5use pyo3::prelude::*;
6
7const VIA_USAGE_PAGE: u16 = 0xff60;
8
9#[cfg_attr(feature = "python", pyclass(get_all, from_py_object))]
11#[derive(Clone, Debug)]
12pub struct KeyboardDeviceInfo {
13 pub vendor_id: u16,
15 pub product_id: u16,
17 pub usage_page: u16,
19 pub manufacturer: Option<String>,
21 pub product: Option<String>,
23 pub serial_number: Option<String>,
25}
26
27#[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}