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