From 3dd652c1d70da608c77d1ded9e6d44774fc10ebc Mon Sep 17 00:00:00 2001 From: jamie Date: Sat, 29 Aug 2026 22:15:55 +0100 Subject: refactor: dedupe helpers, name protocol constants, testable daemon args --- src/hid.rs | 56 +++++++++++++++----------------------------------------- 1 file changed, 15 insertions(+), 41 deletions(-) (limited to 'src/hid.rs') diff --git a/src/hid.rs b/src/hid.rs index 6b09e98..72f67fa 100644 --- a/src/hid.rs +++ b/src/hid.rs @@ -63,40 +63,7 @@ pub struct HidDevice { /// Enumerate hidraw devices matching `vid`/`pid` by reading the sysfs `uevent` /// of each `/sys/class/hidraw/hidrawN`. pub fn find_devices(vid: u16, pid: u16) -> io::Result> { - let mut out = Vec::new(); - for entry in fs::read_dir(HIDRAW_SYSFS)? { - let entry = entry?; - let name = entry.file_name(); - let Some(name) = name.to_str() else { - continue; - }; - if !name.starts_with("hidraw") { - continue; - } - let Some(uevent) = read_sysfs(&entry.path().join("device/uevent")) else { - continue; - }; - let Some((bus, v, p)) = parse_hid_id(&uevent) else { - continue; - }; - if bus != 3 { - continue; // USB only - } - if v == vid && p == pid { - let dev_name = uevent - .lines() - .find(|l| l.starts_with("HID_NAME=")) - .map(|l| l.trim_start_matches("HID_NAME=").to_string()) - .unwrap_or_default(); - out.push(HidDevice { - vid: v, - pid: p, - name: dev_name, - devnode: PathBuf::from("/dev").join(name), - }); - } - } - Ok(out) + find_with(|v, p| v == vid && p == pid) } /// Find the first (only) MMX 150 dongle HID device. @@ -108,6 +75,12 @@ pub fn find_mmx150() -> io::Result> { /// Enumerate all hidraw devices belonging to a vendor. pub fn find_devices_by_vendor(vid: u16) -> io::Result> { + find_with(|v, _| v == vid) +} + +/// Collect USB hidraw devices whose `HID_ID` vendor/product pair matches +/// `keep`. Returns one [`HidDevice`] per match. +fn find_with(mut keep: impl FnMut(u16, u16) -> bool) -> io::Result> { let mut out = Vec::new(); for entry in fs::read_dir(HIDRAW_SYSFS)? { let entry = entry?; @@ -124,8 +97,8 @@ pub fn find_devices_by_vendor(vid: u16) -> io::Result> { let Some((bus, v, p)) = parse_hid_id(&uevent) else { continue; }; - if bus != 3 || v != vid { - continue; + if bus != 3 || !keep(v, p) { + continue; // USB only, filtered by caller } let dev_name = uevent .lines() @@ -160,11 +133,6 @@ impl Hidraw { }) } - /// Returns the underlying raw file descriptor. - pub fn as_raw_fd(&self) -> std::os::fd::RawFd { - self.file.as_raw_fd() - } - /// `HIDIOCGFEATURE`: fetch `report_id` into `data` (report length + 1 /// bytes including the report-id byte). Returns bytes received. pub fn get_feature(&self, report_id: u8, len: usize) -> io::Result> { @@ -266,6 +234,12 @@ impl Hidraw { } } +impl std::os::fd::AsRawFd for Hidraw { + fn as_raw_fd(&self) -> std::os::fd::RawFd { + self.file.as_raw_fd() + } +} + fn read_sysfs(path: &Path) -> Option { fs::read_to_string(path).ok() } -- cgit v1.3.1