#![warn(missing_docs)]
include!(concat!(env!("OUT_DIR"), "/usb_ids.cg.rs"));
pub struct Vendors;
impl Vendors {
pub fn iter() -> impl Iterator<Item = &'static Vendor> {
USB_IDS.values()
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vendor {
id: u16,
name: &'static str,
devices: &'static [Device],
}
impl Vendor {
pub fn id(&self) -> u16 {
self.id
}
pub fn name(&self) -> &'static str {
self.name
}
pub fn devices(&self) -> impl Iterator<Item = &'static Device> {
self.devices.iter()
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Device {
vendor_id: u16,
id: u16,
name: &'static str,
interfaces: &'static [Interface],
}
impl Device {
pub fn from_vid_pid(vid: u16, pid: u16) -> Option<&'static Device> {
let vendor = Vendor::from_id(vid);
vendor.and_then(|v| v.devices().find(|d| d.id == pid))
}
pub fn vendor(&self) -> &'static Vendor {
USB_IDS.get(&self.vendor_id).unwrap()
}
pub fn as_vid_pid(&self) -> (u16, u16) {
(self.vendor_id, self.id)
}
pub fn id(&self) -> u16 {
self.id
}
pub fn name(&self) -> &'static str {
self.name
}
pub fn interfaces(&self) -> impl Iterator<Item = &'static Interface> {
self.interfaces.iter()
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Interface {
id: u8,
name: &'static str,
}
impl Interface {
pub fn id(&self) -> u8 {
self.id
}
pub fn name(&self) -> &'static str {
self.name
}
}
pub trait FromId<T> {
fn from_id(id: T) -> Option<&'static Self>;
}
impl FromId<u16> for Vendor {
fn from_id(id: u16) -> Option<&'static Self> {
USB_IDS.get(&id)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_id() {
let vendor = Vendor::from_id(0x1d6b).unwrap();
assert_eq!(vendor.name(), "Linux Foundation");
assert_eq!(vendor.id(), 0x1d6b);
}
#[test]
fn test_vendor_devices() {
let vendor = Vendor::from_id(0x1d6b).unwrap();
for device in vendor.devices() {
assert_eq!(device.vendor(), vendor);
assert!(!device.name().is_empty());
}
}
#[test]
fn test_from_vid_pid() {
let device = Device::from_vid_pid(0x1d6b, 0x0003).unwrap();
assert_eq!(device.name(), "3.0 root hub");
let (vid, pid) = device.as_vid_pid();
assert_eq!(vid, device.vendor().id());
assert_eq!(pid, device.id());
let device2 = Device::from_vid_pid(vid, pid).unwrap();
assert_eq!(device, device2);
}
}