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    KnownUsagePage, UsagePage, arcade, auxiliary_display, barcode_scanner, battery_system,
6    braille_display, camera_control, consumer, digitizers, eye_head_trackers, fido_alliance,
7    game_controls, generic_desktop, generic_device_controls, haptics, keyboard_keypad, led_page,
8    lighting_illumination, magnetic_stripe_reader, medical_instrument, monitor,
9    physical_input_device, power, scales, sensors, simulation_controls, soc, sport_controls,
10    telephony_device, vesa_virtual_controls, vr_controls,
11};
12
13/// A __Usage ID__, that includes its parent __Usage Page__.
14#[derive(Clone, Copy, PartialEq)]
15pub struct ExtendedUsage {
16    /// The Usage Page.
17    pub page: UsagePage,
18    /// The Usage ID.
19    pub id: u16,
20}
21
22impl ExtendedUsage {
23    /// Create a new `ExtendedUsage` value.
24    pub fn new(page: UsagePage, id: u16) -> Self {
25        Self { page, id }
26    }
27
28    /// Construct a usage page/id from a single integer
29    pub fn from_u32(value: u32) -> Self {
30        let lsb = (value & 0xFFFF) as u16;
31        let msb = (value >> 16) as u16;
32        let page = UsagePage::from_integer(msb);
33        Self { page, id: lsb }
34    }
35
36    /// Extract the usage value if it is a known value.
37    ///
38    /// If this returns `None` it could be for multiple reasons:
39    ///
40    /// 1. The Usage Page does not contain distinct IDs (e.g. Button)
41    /// 2. The Usage Page is unknown or reserved.
42    /// 3. The Usage Page is known but the Usage value is unknown or reserved.
43    pub fn get_known(&self) -> Option<KnownUsage> {
44        let Ident::Known(known_page) = self.page else {
45            return None;
46        };
47        match known_page {
48            KnownUsagePage::Undefined => None,
49            KnownUsagePage::GenericDesktop => generic_desktop::KnownUsage::try_from(self.id)
50                .ok()
51                .map(KnownUsage::GenericDesktop),
52            KnownUsagePage::SimulationControls => {
53                simulation_controls::KnownUsage::try_from(self.id)
54                    .ok()
55                    .map(KnownUsage::SimulationControls)
56            }
57            KnownUsagePage::VrControls => vr_controls::KnownUsage::try_from(self.id)
58                .ok()
59                .map(KnownUsage::VrControls),
60            KnownUsagePage::SportControls => sport_controls::KnownUsage::try_from(self.id)
61                .ok()
62                .map(KnownUsage::SportControls),
63            KnownUsagePage::GameControls => game_controls::KnownUsage::try_from(self.id)
64                .ok()
65                .map(KnownUsage::GameControls),
66            KnownUsagePage::GenericDeviceControls => {
67                generic_device_controls::KnownUsage::try_from(self.id)
68                    .ok()
69                    .map(KnownUsage::GenericDeviceControls)
70            }
71            KnownUsagePage::KeyboardKeypad => keyboard_keypad::KnownUsage::try_from(self.id)
72                .ok()
73                .map(KnownUsage::KeyboardKeypad),
74            KnownUsagePage::Led => led_page::KnownUsage::try_from(self.id)
75                .ok()
76                .map(KnownUsage::Led),
77            KnownUsagePage::Button => Some(KnownUsage::Button(self.id)),
78            KnownUsagePage::Ordinal => Some(KnownUsage::Ordinal(self.id)),
79            KnownUsagePage::TelephonyDevice => telephony_device::KnownUsage::try_from(self.id)
80                .ok()
81                .map(KnownUsage::TelephonyDevice),
82            KnownUsagePage::Consumer => consumer::KnownUsage::try_from(self.id)
83                .ok()
84                .map(KnownUsage::Consumer),
85            KnownUsagePage::Digitizers => digitizers::KnownUsage::try_from(self.id)
86                .ok()
87                .map(KnownUsage::Digitizers),
88            KnownUsagePage::Haptics => haptics::KnownUsage::try_from(self.id)
89                .ok()
90                .map(KnownUsage::Haptics),
91            KnownUsagePage::PhysicalInputDevice => {
92                physical_input_device::KnownUsage::try_from(self.id)
93                    .ok()
94                    .map(KnownUsage::PhysicalInputDevice)
95            }
96            KnownUsagePage::Unicode => Some(KnownUsage::Unicode(self.id)),
97            KnownUsagePage::Soc => soc::KnownUsage::try_from(self.id).ok().map(KnownUsage::Soc),
98            KnownUsagePage::EyeAndHeadTrackers => eye_head_trackers::KnownUsage::try_from(self.id)
99                .ok()
100                .map(KnownUsage::EyeAndHeadTrackers),
101            KnownUsagePage::AuxiliaryDisplay => auxiliary_display::KnownUsage::try_from(self.id)
102                .ok()
103                .map(KnownUsage::AuxiliaryDisplay),
104            KnownUsagePage::Sensors => sensors::KnownUsage::try_from(self.id)
105                .ok()
106                .map(KnownUsage::Sensors),
107            KnownUsagePage::MedicalInstrument => medical_instrument::KnownUsage::try_from(self.id)
108                .ok()
109                .map(KnownUsage::MedicalInstrument),
110            KnownUsagePage::BrailleDisplay => braille_display::KnownUsage::try_from(self.id)
111                .ok()
112                .map(KnownUsage::BrailleDisplay),
113            KnownUsagePage::LightingAndIllumination => {
114                lighting_illumination::KnownUsage::try_from(self.id)
115                    .ok()
116                    .map(KnownUsage::LightingAndIllumination)
117            }
118            KnownUsagePage::Monitor => monitor::KnownUsage::try_from(self.id)
119                .ok()
120                .map(KnownUsage::Monitor),
121            KnownUsagePage::MonitorEnumerated => Some(KnownUsage::MonitorEnumerated(self.id)),
122            KnownUsagePage::VesaVirtualControls => {
123                vesa_virtual_controls::KnownUsage::try_from(self.id)
124                    .ok()
125                    .map(KnownUsage::VesaVirtualControls)
126            }
127            KnownUsagePage::Power => power::KnownUsage::try_from(self.id)
128                .ok()
129                .map(KnownUsage::Power),
130            KnownUsagePage::BatterySystem => battery_system::KnownUsage::try_from(self.id)
131                .ok()
132                .map(KnownUsage::BatterySystem),
133            KnownUsagePage::BarcodeScanner => barcode_scanner::KnownUsage::try_from(self.id)
134                .ok()
135                .map(KnownUsage::BarcodeScanner),
136            KnownUsagePage::Scales => scales::KnownUsage::try_from(self.id)
137                .ok()
138                .map(KnownUsage::Scales),
139            KnownUsagePage::MagneticStripeReader => {
140                magnetic_stripe_reader::KnownUsage::try_from(self.id)
141                    .ok()
142                    .map(KnownUsage::MagneticStripeReader)
143            }
144            KnownUsagePage::CameraControl => camera_control::KnownUsage::try_from(self.id)
145                .ok()
146                .map(KnownUsage::CameraControl),
147            KnownUsagePage::Arcade => arcade::KnownUsage::try_from(self.id)
148                .ok()
149                .map(KnownUsage::Arcade),
150            KnownUsagePage::GamingDevice => Some(KnownUsage::GamingDevice(self.id)),
151            KnownUsagePage::FidoAlliance => fido_alliance::KnownUsage::try_from(self.id)
152                .ok()
153                .map(KnownUsage::FidoAlliance),
154        }
155    }
156}
157
158/// A __Usage ID__, that does not encode its parent page.
159#[derive(Clone, PartialEq)]
160pub enum Usage {
161    /// A Usage value that remembers its parent page.
162    Known(KnownUsage),
163    /// A standalone Usage value that cannot be decoded without page context.
164    Unknown(u16),
165}
166
167impl Usage {
168    /// Create a new `Usage` value, in the context of a known Usage Page.
169    pub fn new(page: UsagePage, id: u16) -> Self {
170        match ExtendedUsage::new(page, id).get_known() {
171            Some(known) => Usage::Known(known),
172            None => Usage::Unknown(id),
173        }
174    }
175
176    /// Construct a usage without `UsagePage` context.
177    pub fn without_page(id: u16) -> Self {
178        Usage::Unknown(id)
179    }
180}
181
182/// A well-known usage id.
183#[expect(missing_docs)]
184#[derive(Clone, PartialEq)]
185pub enum KnownUsage {
186    GenericDesktop(generic_desktop::KnownUsage),
187    SimulationControls(simulation_controls::KnownUsage),
188    VrControls(vr_controls::KnownUsage),
189    SportControls(sport_controls::KnownUsage),
190    GameControls(game_controls::KnownUsage),
191    GenericDeviceControls(generic_device_controls::KnownUsage),
192    KeyboardKeypad(keyboard_keypad::KnownUsage),
193    Led(led_page::KnownUsage),
194    Button(u16),
195    Ordinal(u16),
196    TelephonyDevice(telephony_device::KnownUsage),
197    Consumer(consumer::KnownUsage),
198    Digitizers(digitizers::KnownUsage),
199    Haptics(haptics::KnownUsage),
200    PhysicalInputDevice(physical_input_device::KnownUsage),
201    Unicode(u16),
202    Soc(soc::KnownUsage),
203    EyeAndHeadTrackers(eye_head_trackers::KnownUsage),
204    AuxiliaryDisplay(auxiliary_display::KnownUsage),
205    Sensors(sensors::KnownUsage),
206    MedicalInstrument(medical_instrument::KnownUsage),
207    BrailleDisplay(braille_display::KnownUsage),
208    LightingAndIllumination(lighting_illumination::KnownUsage),
209    Monitor(monitor::KnownUsage),
210    MonitorEnumerated(u16),
211    VesaVirtualControls(vesa_virtual_controls::KnownUsage),
212    Power(power::KnownUsage),
213    BatterySystem(battery_system::KnownUsage),
214    BarcodeScanner(barcode_scanner::KnownUsage),
215    Scales(scales::KnownUsage),
216    MagneticStripeReader(magnetic_stripe_reader::KnownUsage),
217    CameraControl(camera_control::KnownUsage),
218    Arcade(arcade::KnownUsage),
219    GamingDevice(u16),
220    FidoAlliance(fido_alliance::KnownUsage),
221}
222
223#[cfg(feature = "std")]
224mod std_impls {
225    use std::fmt::{self, Debug, Display};
226
227    use super::*;
228
229    impl Debug for ExtendedUsage {
230        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231            let mut debug_struct = f.debug_struct("Usage");
232            debug_struct.field("page", &self.page);
233
234            if let Some(known) = self.get_known() {
235                debug_struct.field("id", &known);
236            } else {
237                debug_struct.field("id", &format_args!("{:#04x}", self.id));
238            }
239            debug_struct.finish()
240        }
241    }
242
243    impl Debug for Usage {
244        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245            let mut debug_struct = f.debug_struct("Usage");
246
247            // Note: we don't print the `page` value, since it was
248            // not meant to be encoded in this item.
249
250            match self {
251                Usage::Known(usage) => {
252                    debug_struct.field("id", &usage);
253                }
254                Usage::Unknown(id) => {
255                    debug_struct.field("id", &id);
256                }
257            }
258            debug_struct.finish()
259        }
260    }
261
262    impl Debug for KnownUsage {
263        // Only prints the inner value.
264        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
265            match self {
266                Self::Button(value)
267                | Self::Ordinal(value)
268                | Self::Unicode(value)
269                | Self::MonitorEnumerated(value)
270                | Self::GamingDevice(value) => {
271                    // 16-bit usage ID without a unique name.
272                    Debug::fmt(&value, f)
273                }
274                Self::GenericDesktop(value) => value.fmt(f),
275                Self::SimulationControls(value) => value.fmt(f),
276                Self::VrControls(value) => value.fmt(f),
277                Self::SportControls(value) => value.fmt(f),
278                Self::GameControls(value) => value.fmt(f),
279                Self::GenericDeviceControls(value) => value.fmt(f),
280                Self::KeyboardKeypad(value) => value.fmt(f),
281                Self::Led(value) => value.fmt(f),
282                Self::TelephonyDevice(value) => value.fmt(f),
283                Self::Consumer(value) => value.fmt(f),
284                Self::Digitizers(value) => value.fmt(f),
285                Self::Haptics(value) => value.fmt(f),
286                Self::PhysicalInputDevice(value) => value.fmt(f),
287                Self::Soc(value) => value.fmt(f),
288                Self::EyeAndHeadTrackers(value) => value.fmt(f),
289                Self::AuxiliaryDisplay(value) => value.fmt(f),
290                Self::Sensors(value) => value.fmt(f),
291                Self::MedicalInstrument(value) => value.fmt(f),
292                Self::BrailleDisplay(value) => value.fmt(f),
293                Self::LightingAndIllumination(value) => value.fmt(f),
294                Self::Monitor(value) => value.fmt(f),
295                Self::VesaVirtualControls(value) => value.fmt(f),
296                Self::Power(value) => value.fmt(f),
297                Self::BatterySystem(value) => value.fmt(f),
298                Self::BarcodeScanner(value) => value.fmt(f),
299                Self::Scales(value) => value.fmt(f),
300                Self::MagneticStripeReader(value) => value.fmt(f),
301                Self::CameraControl(value) => value.fmt(f),
302                Self::Arcade(value) => value.fmt(f),
303                Self::FidoAlliance(value) => value.fmt(f),
304            }
305        }
306    }
307
308    impl Display 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                    Display::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 Usage {
355        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356            // Note: we don't print the `page` value, since it was
357            // not meant to be encoded in this item.
358
359            match self {
360                Usage::Known(usage) => Display::fmt(&usage, f),
361                Usage::Unknown(id) => Display::fmt(&format_args!("{id:#04x}"), f),
362            }
363        }
364    }
365}