hidra
A pure-Rust HID library with a unified async API (with blocking .wait() on
native targets, like nusb), a WebHID backend for WebAssembly, and standalone
HID report-descriptor primitives.
No C library is linked. One Hidra / HidDevice regardless of backend:
| Platform | Backend | Notes |
|---|---|---|
| Linux | hidraw device nodes, sysfs enumeration |
no libudev dependency |
| Windows | hid.dll + SetupAPI (via windows-sys declarations) |
|
| macOS | IOHIDManager (direct framework FFI) | |
| any platform nusb supports | raw USB transfers via nusb | optional nusb feature, swaps in a pure-Rust USB transport |
| Browsers | WebHID via web-sys |
same Hidra/HidDevice, await-only |
Quick start
Every I/O method returns a future. On native, bring MaybeFuture into scope
and call .wait() to run it blocking:
use MaybeFuture;
let api = new?;
for dev in api.device_list
let device = api.open.wait?;
device.write.wait?; // report ID 0 + payload
let mut buf = ;
let len = device.read.wait?; // one input report
See examples/ for runnable versions (cargo run --example enumerate).
Async and blocking
Following nusb's design, every Hidra / HidDevice method returns an
impl Future. Drive it either way:
.awaitit in any async runtime (the futures are runtime-agnostic: plainWakerwake-ups, no tokio/async-std dependency)..wait()it to block the current thread (a tiny built-in executor). This is theMaybeFutureextension trait, available on native targets only;wasm32cannot block, so there you must.await.
let len = device.read.await?; // async
let len = device.read.wait?; // blocking (native)
Input reads genuinely wait on the OS (a poll(2) reactor on Linux,
overlapped-event waits on Windows, the IOHIDManager callback queue on macOS,
nusb's own I/O with the nusb feature, inputreport events on WebHID).
read resolves with exactly one input report (never empty); for a timeout
use your runtime's combinator (e.g. tokio::time::timeout). On unplug it
fails with HidError::Disconnected, and the read future is cancel-safe:
dropping it never loses a report. Writes and feature reports complete
promptly; their futures simply run the synchronous OS call when polled.