Skip to main content

hid_types/item/
usage.rs

1//! Types that contain all the information in Usage tags.
2
3use crate::Ident;
4use crate::id::usage::*;
5
6/// A __Usage ID__, that includes its parent __Usage Page__.
7#[derive(Clone, Copy, PartialEq)]
8pub struct ExtendedUsage {
9    /// The Usage Page.
10    pub page: UsagePage,
11    /// The Usage ID.
12    pub id: Usage,
13}
14
15impl ExtendedUsage {
16    /// Create a new `ExtendedUsage` value.
17    pub fn new(page: UsagePage, id: u16) -> Self {
18        let id = Usage::new(page, id);
19        Self { page, id }
20    }
21
22    /// Construct a usage page/id from a single integer
23    pub fn from_u32(value: u32) -> Self {
24        let lsb = (value & 0xFFFF) as u16;
25        let msb = (value >> 16) as u16;
26        let page = UsagePage::from_integer(msb);
27        let id = Usage::new(page, lsb);
28        Self { page, id }
29    }
30
31    /// Convert to a single integer containing both usage page and usage id.
32    ///
33    /// The usage page will be in the upper 16 bits, and the usage id will be
34    /// in the lower 16 bits.
35    pub fn to_integer(&self) -> u32 {
36        let page = self.page.to_integer();
37        let id = self.id.to_integer();
38        (page as u32) << 16 | (id as u32)
39    }
40}
41
42/// A __Usage ID__, that does not encode its parent page.
43#[derive(Clone, Copy, PartialEq)]
44pub enum Usage {
45    /// A Usage value that remembers its parent page.
46    Known(KnownUsage),
47    /// A standalone Usage value that cannot be decoded without page context.
48    Unknown(u16),
49}
50
51// Useful when iterating over a range of Usage values.
52impl PartialOrd for Usage {
53    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
54        let this = self.to_integer();
55        let other = other.to_integer();
56        this.partial_cmp(&other)
57    }
58}
59
60impl Usage {
61    /// Create a new `Usage` value, using context from a specific Usage Page.
62    ///
63    /// If the Usage Page is known, this will attempt to return a `KnownUsage`
64    /// variant corresponding to that page.
65    pub fn new(page: UsagePage, id: u16) -> Self {
66        let usage = match page {
67            Ident::Known(known_page) => KnownUsage::from_page_and_id(known_page, id),
68            Ident::Reserved(_) => None,
69        };
70
71        match usage {
72            Some(known) => Usage::Known(known),
73            None => Usage::Unknown(id),
74        }
75    }
76
77    /// Construct a usage without `UsagePage` context.
78    pub fn without_page(id: u16) -> Self {
79        Usage::Unknown(id)
80    }
81
82    /// Return the u16 value of the usage id.
83    pub fn to_integer(&self) -> u16 {
84        match self {
85            Usage::Known(known_usage) => known_usage.to_integer(),
86            Usage::Unknown(value) => *value,
87        }
88    }
89
90    /// Return the usage value that numerically follows this one.
91    ///
92    /// This function will return `None` if the usage id overflows
93    /// `u16::MAX`.
94    pub fn successor(&self, page: UsagePage) -> Option<Self> {
95        let id = self.to_integer().checked_add(1)?;
96        Some(Usage::new(page, id))
97    }
98}
99
100/// A well-known usage id.
101#[expect(missing_docs)]
102#[derive(Clone, Copy, PartialEq)]
103#[non_exhaustive]
104pub enum KnownUsage {
105    GenericDesktop(generic_desktop::KnownUsage),
106    SimulationControls(simulation_controls::KnownUsage),
107    VrControls(vr_controls::KnownUsage),
108    SportControls(sport_controls::KnownUsage),
109    GameControls(game_controls::KnownUsage),
110    GenericDeviceControls(generic_device_controls::KnownUsage),
111    KeyboardKeypad(keyboard_keypad::KnownUsage),
112    Led(led_page::KnownUsage),
113    Button(u16),
114    Ordinal(u16),
115    TelephonyDevice(telephony_device::KnownUsage),
116    Consumer(consumer::KnownUsage),
117    Digitizers(digitizers::KnownUsage),
118    Haptics(haptics::KnownUsage),
119    PhysicalInputDevice(physical_input_device::KnownUsage),
120    Unicode(u16),
121    Soc(soc::KnownUsage),
122    EyeAndHeadTrackers(eye_head_trackers::KnownUsage),
123    AuxiliaryDisplay(auxiliary_display::KnownUsage),
124    Sensors(sensors::KnownUsage),
125    MedicalInstrument(medical_instrument::KnownUsage),
126    BrailleDisplay(braille_display::KnownUsage),
127    LightingAndIllumination(lighting_illumination::KnownUsage),
128    Monitor(monitor::KnownUsage),
129    MonitorEnumerated(u16),
130    VesaVirtualControls(vesa_virtual_controls::KnownUsage),
131    Power(power::KnownUsage),
132    BatterySystem(battery_system::KnownUsage),
133    BarcodeScanner(barcode_scanner::KnownUsage),
134    Scales(scales::KnownUsage),
135    MagneticStripeReader(magnetic_stripe_reader::KnownUsage),
136    CameraControl(camera_control::KnownUsage),
137    Arcade(arcade::KnownUsage),
138    GamingDevice(u16),
139    FidoAlliance(fido_alliance::KnownUsage),
140}
141
142impl KnownUsage {
143    /// Extract the usage value if it is a known value.
144    ///
145    /// If this returns `None` it could be for multiple reasons:
146    ///
147    /// 1. The Usage Page does not contain distinct IDs (e.g. Button)
148    /// 2. The Usage Page is unknown or reserved.
149    /// 3. The Usage Page is known but the Usage value is unknown or reserved.
150    pub fn from_page_and_id(page: KnownUsagePage, id: u16) -> Option<Self> {
151        match page {
152            KnownUsagePage::Undefined => None,
153            KnownUsagePage::GenericDesktop => generic_desktop::KnownUsage::try_from(id)
154                .ok()
155                .map(KnownUsage::GenericDesktop),
156            KnownUsagePage::SimulationControls => simulation_controls::KnownUsage::try_from(id)
157                .ok()
158                .map(KnownUsage::SimulationControls),
159            KnownUsagePage::VrControls => vr_controls::KnownUsage::try_from(id)
160                .ok()
161                .map(KnownUsage::VrControls),
162            KnownUsagePage::SportControls => sport_controls::KnownUsage::try_from(id)
163                .ok()
164                .map(KnownUsage::SportControls),
165            KnownUsagePage::GameControls => game_controls::KnownUsage::try_from(id)
166                .ok()
167                .map(KnownUsage::GameControls),
168            KnownUsagePage::GenericDeviceControls => {
169                generic_device_controls::KnownUsage::try_from(id)
170                    .ok()
171                    .map(KnownUsage::GenericDeviceControls)
172            }
173            KnownUsagePage::KeyboardKeypad => keyboard_keypad::KnownUsage::try_from(id)
174                .ok()
175                .map(KnownUsage::KeyboardKeypad),
176            KnownUsagePage::Led => led_page::KnownUsage::try_from(id).ok().map(KnownUsage::Led),
177            KnownUsagePage::Button => Some(KnownUsage::Button(id)),
178            KnownUsagePage::Ordinal => Some(KnownUsage::Ordinal(id)),
179            KnownUsagePage::TelephonyDevice => telephony_device::KnownUsage::try_from(id)
180                .ok()
181                .map(KnownUsage::TelephonyDevice),
182            KnownUsagePage::Consumer => consumer::KnownUsage::try_from(id)
183                .ok()
184                .map(KnownUsage::Consumer),
185            KnownUsagePage::Digitizers => digitizers::KnownUsage::try_from(id)
186                .ok()
187                .map(KnownUsage::Digitizers),
188            KnownUsagePage::Haptics => haptics::KnownUsage::try_from(id)
189                .ok()
190                .map(KnownUsage::Haptics),
191            KnownUsagePage::PhysicalInputDevice => physical_input_device::KnownUsage::try_from(id)
192                .ok()
193                .map(KnownUsage::PhysicalInputDevice),
194            KnownUsagePage::Unicode => Some(KnownUsage::Unicode(id)),
195            KnownUsagePage::Soc => soc::KnownUsage::try_from(id).ok().map(KnownUsage::Soc),
196            KnownUsagePage::EyeAndHeadTrackers => eye_head_trackers::KnownUsage::try_from(id)
197                .ok()
198                .map(KnownUsage::EyeAndHeadTrackers),
199            KnownUsagePage::AuxiliaryDisplay => auxiliary_display::KnownUsage::try_from(id)
200                .ok()
201                .map(KnownUsage::AuxiliaryDisplay),
202            KnownUsagePage::Sensors => sensors::KnownUsage::try_from(id)
203                .ok()
204                .map(KnownUsage::Sensors),
205            KnownUsagePage::MedicalInstrument => medical_instrument::KnownUsage::try_from(id)
206                .ok()
207                .map(KnownUsage::MedicalInstrument),
208            KnownUsagePage::BrailleDisplay => braille_display::KnownUsage::try_from(id)
209                .ok()
210                .map(KnownUsage::BrailleDisplay),
211            KnownUsagePage::LightingAndIllumination => {
212                lighting_illumination::KnownUsage::try_from(id)
213                    .ok()
214                    .map(KnownUsage::LightingAndIllumination)
215            }
216            KnownUsagePage::Monitor => monitor::KnownUsage::try_from(id)
217                .ok()
218                .map(KnownUsage::Monitor),
219            KnownUsagePage::MonitorEnumerated => Some(KnownUsage::MonitorEnumerated(id)),
220            KnownUsagePage::VesaVirtualControls => vesa_virtual_controls::KnownUsage::try_from(id)
221                .ok()
222                .map(KnownUsage::VesaVirtualControls),
223            KnownUsagePage::Power => power::KnownUsage::try_from(id).ok().map(KnownUsage::Power),
224            KnownUsagePage::BatterySystem => battery_system::KnownUsage::try_from(id)
225                .ok()
226                .map(KnownUsage::BatterySystem),
227            KnownUsagePage::BarcodeScanner => barcode_scanner::KnownUsage::try_from(id)
228                .ok()
229                .map(KnownUsage::BarcodeScanner),
230            KnownUsagePage::Scales => scales::KnownUsage::try_from(id)
231                .ok()
232                .map(KnownUsage::Scales),
233            KnownUsagePage::MagneticStripeReader => {
234                magnetic_stripe_reader::KnownUsage::try_from(id)
235                    .ok()
236                    .map(KnownUsage::MagneticStripeReader)
237            }
238            KnownUsagePage::CameraControl => camera_control::KnownUsage::try_from(id)
239                .ok()
240                .map(KnownUsage::CameraControl),
241            KnownUsagePage::Arcade => arcade::KnownUsage::try_from(id)
242                .ok()
243                .map(KnownUsage::Arcade),
244            KnownUsagePage::GamingDevice => Some(KnownUsage::GamingDevice(id)),
245            KnownUsagePage::FidoAlliance => fido_alliance::KnownUsage::try_from(id)
246                .ok()
247                .map(KnownUsage::FidoAlliance),
248        }
249    }
250
251    fn to_integer(self) -> u16 {
252        match self {
253            KnownUsage::GenericDesktop(usage) => usage.into(),
254            KnownUsage::SimulationControls(usage) => usage.into(),
255            KnownUsage::VrControls(usage) => usage.into(),
256            KnownUsage::SportControls(usage) => usage.into(),
257            KnownUsage::GameControls(usage) => usage.into(),
258            KnownUsage::GenericDeviceControls(usage) => usage.into(),
259            KnownUsage::KeyboardKeypad(usage) => usage.into(),
260            KnownUsage::Led(usage) => usage.into(),
261            KnownUsage::Button(usage) => usage,
262            KnownUsage::Ordinal(usage) => usage,
263            KnownUsage::TelephonyDevice(usage) => usage.into(),
264            KnownUsage::Consumer(usage) => usage.into(),
265            KnownUsage::Digitizers(usage) => usage.into(),
266            KnownUsage::Haptics(usage) => usage.into(),
267            KnownUsage::PhysicalInputDevice(usage) => usage.into(),
268            KnownUsage::Unicode(usage) => usage,
269            KnownUsage::Soc(usage) => usage.into(),
270            KnownUsage::EyeAndHeadTrackers(usage) => usage.into(),
271            KnownUsage::AuxiliaryDisplay(usage) => usage.into(),
272            KnownUsage::Sensors(usage) => usage.into(),
273            KnownUsage::MedicalInstrument(usage) => usage.into(),
274            KnownUsage::BrailleDisplay(usage) => usage.into(),
275            KnownUsage::LightingAndIllumination(usage) => usage.into(),
276            KnownUsage::Monitor(usage) => usage.into(),
277            KnownUsage::MonitorEnumerated(usage) => usage,
278            KnownUsage::VesaVirtualControls(usage) => usage.into(),
279            KnownUsage::Power(usage) => usage.into(),
280            KnownUsage::BatterySystem(usage) => usage.into(),
281            KnownUsage::BarcodeScanner(usage) => usage.into(),
282            KnownUsage::Scales(usage) => usage.into(),
283            KnownUsage::MagneticStripeReader(usage) => usage.into(),
284            KnownUsage::CameraControl(usage) => usage.into(),
285            KnownUsage::Arcade(usage) => usage.into(),
286            KnownUsage::GamingDevice(usage) => usage,
287            KnownUsage::FidoAlliance(usage) => usage.into(),
288        }
289    }
290}
291
292#[cfg(feature = "std")]
293mod std_impls {
294    use std::fmt::{self, Debug, Display};
295
296    use super::*;
297
298    impl Debug for ExtendedUsage {
299        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300            let mut debug_struct = f.debug_struct("Usage");
301            debug_struct.field("page", &self.page);
302            debug_struct.field("id", &self.id);
303            debug_struct.finish()
304        }
305    }
306
307    impl Debug for Usage {
308        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309            let mut debug_struct = f.debug_struct("Usage");
310
311            // Note: we don't print the `page` value, since it was
312            // not meant to be encoded in this item.
313
314            match self {
315                Usage::Known(usage) => {
316                    debug_struct.field("id", &usage);
317                }
318                Usage::Unknown(id) => {
319                    debug_struct.field("id", &id);
320                }
321            }
322            debug_struct.finish()
323        }
324    }
325
326    impl Debug for KnownUsage {
327        // Only prints the inner value.
328        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329            match self {
330                Self::Button(value)
331                | Self::Ordinal(value)
332                | Self::Unicode(value)
333                | Self::MonitorEnumerated(value)
334                | Self::GamingDevice(value) => {
335                    // 16-bit usage ID without a unique name.
336                    Debug::fmt(&value, f)
337                }
338                Self::GenericDesktop(value) => value.fmt(f),
339                Self::SimulationControls(value) => value.fmt(f),
340                Self::VrControls(value) => value.fmt(f),
341                Self::SportControls(value) => value.fmt(f),
342                Self::GameControls(value) => value.fmt(f),
343                Self::GenericDeviceControls(value) => value.fmt(f),
344                Self::KeyboardKeypad(value) => value.fmt(f),
345                Self::Led(value) => value.fmt(f),
346                Self::TelephonyDevice(value) => value.fmt(f),
347                Self::Consumer(value) => value.fmt(f),
348                Self::Digitizers(value) => value.fmt(f),
349                Self::Haptics(value) => value.fmt(f),
350                Self::PhysicalInputDevice(value) => value.fmt(f),
351                Self::Soc(value) => value.fmt(f),
352                Self::EyeAndHeadTrackers(value) => value.fmt(f),
353                Self::AuxiliaryDisplay(value) => value.fmt(f),
354                Self::Sensors(value) => value.fmt(f),
355                Self::MedicalInstrument(value) => value.fmt(f),
356                Self::BrailleDisplay(value) => value.fmt(f),
357                Self::LightingAndIllumination(value) => value.fmt(f),
358                Self::Monitor(value) => value.fmt(f),
359                Self::VesaVirtualControls(value) => value.fmt(f),
360                Self::Power(value) => value.fmt(f),
361                Self::BatterySystem(value) => value.fmt(f),
362                Self::BarcodeScanner(value) => value.fmt(f),
363                Self::Scales(value) => value.fmt(f),
364                Self::MagneticStripeReader(value) => value.fmt(f),
365                Self::CameraControl(value) => value.fmt(f),
366                Self::Arcade(value) => value.fmt(f),
367                Self::FidoAlliance(value) => value.fmt(f),
368            }
369        }
370    }
371
372    impl Display for KnownUsage {
373        // Only prints the inner value.
374        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
375            match self {
376                Self::Button(value)
377                | Self::Ordinal(value)
378                | Self::Unicode(value)
379                | Self::MonitorEnumerated(value)
380                | Self::GamingDevice(value) => {
381                    // 16-bit usage ID without a unique name.
382                    Display::fmt(&value, f)
383                }
384                Self::GenericDesktop(value) => value.fmt(f),
385                Self::SimulationControls(value) => value.fmt(f),
386                Self::VrControls(value) => value.fmt(f),
387                Self::SportControls(value) => value.fmt(f),
388                Self::GameControls(value) => value.fmt(f),
389                Self::GenericDeviceControls(value) => value.fmt(f),
390                Self::KeyboardKeypad(value) => value.fmt(f),
391                Self::Led(value) => value.fmt(f),
392                Self::TelephonyDevice(value) => value.fmt(f),
393                Self::Consumer(value) => value.fmt(f),
394                Self::Digitizers(value) => value.fmt(f),
395                Self::Haptics(value) => value.fmt(f),
396                Self::PhysicalInputDevice(value) => value.fmt(f),
397                Self::Soc(value) => value.fmt(f),
398                Self::EyeAndHeadTrackers(value) => value.fmt(f),
399                Self::AuxiliaryDisplay(value) => value.fmt(f),
400                Self::Sensors(value) => value.fmt(f),
401                Self::MedicalInstrument(value) => value.fmt(f),
402                Self::BrailleDisplay(value) => value.fmt(f),
403                Self::LightingAndIllumination(value) => value.fmt(f),
404                Self::Monitor(value) => value.fmt(f),
405                Self::VesaVirtualControls(value) => value.fmt(f),
406                Self::Power(value) => value.fmt(f),
407                Self::BatterySystem(value) => value.fmt(f),
408                Self::BarcodeScanner(value) => value.fmt(f),
409                Self::Scales(value) => value.fmt(f),
410                Self::MagneticStripeReader(value) => value.fmt(f),
411                Self::CameraControl(value) => value.fmt(f),
412                Self::Arcade(value) => value.fmt(f),
413                Self::FidoAlliance(value) => value.fmt(f),
414            }
415        }
416    }
417
418    impl Display for Usage {
419        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
420            // Note: we don't print the `page` value, since it was
421            // not meant to be encoded in this item.
422
423            match self {
424                Usage::Known(usage) => Display::fmt(&usage, f),
425                Usage::Unknown(id) => Display::fmt(&format_args!("{id:#04x}"), f),
426            }
427        }
428    }
429}