1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
//! //! Rust wrappers for the [USB ID Repository](http://www.linux-usb.org/usb-ids.html). //! //! The USB ID Repository is the canonical source of USB device information for most //! Linux userspaces; this crate vendors the USB ID database to allow non-Linux hosts to //! access the same canonical information. //! //! # Usage //! //! Iterating over all known vendors: //! //! ```rust //! use usb_ids::Vendors; //! //! for vendor in Vendors::iter() { //! for device in vendor.devices() { //! println!("vendor: {}, device: {}", vendor.name(), device.name()); //! } //! } //! ``` //! //! See the individual documentation for each structure for more details. //! #![warn(missing_docs)] // Codegen: introduces USB_IDS, a phf::Map<u16, Vendor>. include!(concat!(env!("OUT_DIR"), "/usb_ids.cg.rs")); /// An abstraction for iterating over all vendors in the USB database. pub struct Vendors; impl Vendors { /// Returns an iterator over all vendors in the USB database. pub fn iter() -> impl Iterator<Item = &'static Vendor> { USB_IDS.values() } } /// Represents a USB device vendor in the USB database. /// /// Every device vendor has a vendor ID, a pretty name, and a /// list of associated [`Device`]s. #[derive(Clone, Copy, Debug, PartialEq)] pub struct Vendor { id: u16, name: &'static str, devices: &'static [Device], } impl Vendor { /// Returns the vendor's ID. pub fn id(&self) -> u16 { self.id } /// Returns the vendor's name. pub fn name(&self) -> &'static str { self.name } /// Returns an iterator over the vendor's devices. pub fn devices(&self) -> impl Iterator<Item = &'static Device> { self.devices.iter() } } /// Represents a single device in the USB database. /// /// Every device has a corresponding vendor, a device ID, a pretty name, /// and a list of associated [`Interface`]s. #[derive(Clone, Copy, Debug, PartialEq)] pub struct Device { vendor_id: u16, id: u16, name: &'static str, interfaces: &'static [Interface], } impl Device { /// Returns the [`Vendor`] that this device belongs to. /// /// Looking up a vendor by device is cheap (`O(1)`). pub fn vendor(&self) -> &'static Vendor { USB_IDS.get(&self.vendor_id).unwrap() } /// Returns a tuple of (vendor id, device/"product" id) for this device. /// /// This is convenient for interactions with other USB libraries. pub fn as_vid_pid(&self) -> (u16, u16) { (self.vendor_id, self.id) } /// Returns the device's ID. pub fn id(&self) -> u16 { self.id } /// Returns the device's name. pub fn name(&self) -> &'static str { self.name } /// Returns an iterator over the device's interfaces. /// /// **NOTE**: The USB database does not include interface information for /// most devices. This list is not authoritative. pub fn interfaces(&self) -> impl Iterator<Item = &'static Interface> { self.interfaces.iter() } } /// Represents an interface to a USB device in the USB database. /// /// Every interface has an interface ID (which is an index on the device) /// and a pretty name. /// /// **NOTE**: The USB database is not a canonical or authoritative source /// of interface information for devices. Users who wish to discover interfaces /// on their USB devices should query those devices directly. #[derive(Clone, Copy, Debug, PartialEq)] pub struct Interface { id: u8, name: &'static str, } impl Interface { /// Returns the interface's ID. pub fn id(&self) -> u8 { self.id } /// Returns the interface's name. pub fn name(&self) -> &'static str { self.name } } /// A convenience trait for retrieving a top-level entity (like a [`Vendor`]) from the USB /// database by its unique ID. // NOTE(ww): This trait will be generally useful once we support other top-level // entities in `usb.ids` (like language, country code, HID codes, etc). pub trait FromId<T> { /// Returns the entity corresponding to `id`, or `None` if none exists. 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()); } } }