use crate::Ident;
use crate::id::usage::{
KnownUsagePage, UsagePage, arcade, auxiliary_display, barcode_scanner, battery_system,
braille_display, camera_control, consumer, digitizers, eye_head_trackers, fido_alliance,
game_controls, generic_desktop, generic_device_controls, haptics, keyboard_keypad, led_page,
lighting_illumination, magnetic_stripe_reader, medical_instrument, monitor,
physical_input_device, power, scales, sensors, simulation_controls, soc, sport_controls,
telephony_device, vesa_virtual_controls, vr_controls,
};
#[derive(Clone, Copy, PartialEq)]
pub struct ExtendedUsage {
pub page: UsagePage,
pub id: u16,
}
impl ExtendedUsage {
pub fn new(page: UsagePage, id: u16) -> Self {
Self { page, id }
}
pub fn from_u32(value: u32) -> Self {
let lsb = (value & 0xFFFF) as u16;
let msb = (value >> 16) as u16;
let page = UsagePage::from_integer(msb);
Self { page, id: lsb }
}
pub fn get_known(&self) -> Option<KnownUsage> {
let Ident::Known(known_page) = self.page else {
return None;
};
match known_page {
KnownUsagePage::Undefined => None,
KnownUsagePage::GenericDesktop => generic_desktop::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::GenericDesktop),
KnownUsagePage::SimulationControls => {
simulation_controls::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::SimulationControls)
}
KnownUsagePage::VrControls => vr_controls::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::VrControls),
KnownUsagePage::SportControls => sport_controls::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::SportControls),
KnownUsagePage::GameControls => game_controls::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::GameControls),
KnownUsagePage::GenericDeviceControls => {
generic_device_controls::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::GenericDeviceControls)
}
KnownUsagePage::KeyboardKeypad => keyboard_keypad::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::KeyboardKeypad),
KnownUsagePage::Led => led_page::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::Led),
KnownUsagePage::Button => Some(KnownUsage::Button(self.id)),
KnownUsagePage::Ordinal => Some(KnownUsage::Ordinal(self.id)),
KnownUsagePage::TelephonyDevice => telephony_device::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::TelephonyDevice),
KnownUsagePage::Consumer => consumer::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::Consumer),
KnownUsagePage::Digitizers => digitizers::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::Digitizers),
KnownUsagePage::Haptics => haptics::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::Haptics),
KnownUsagePage::PhysicalInputDevice => {
physical_input_device::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::PhysicalInputDevice)
}
KnownUsagePage::Unicode => Some(KnownUsage::Unicode(self.id)),
KnownUsagePage::Soc => soc::KnownUsage::try_from(self.id).ok().map(KnownUsage::Soc),
KnownUsagePage::EyeAndHeadTrackers => eye_head_trackers::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::EyeAndHeadTrackers),
KnownUsagePage::AuxiliaryDisplay => auxiliary_display::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::AuxiliaryDisplay),
KnownUsagePage::Sensors => sensors::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::Sensors),
KnownUsagePage::MedicalInstrument => medical_instrument::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::MedicalInstrument),
KnownUsagePage::BrailleDisplay => braille_display::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::BrailleDisplay),
KnownUsagePage::LightingAndIllumination => {
lighting_illumination::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::LightingAndIllumination)
}
KnownUsagePage::Monitor => monitor::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::Monitor),
KnownUsagePage::MonitorEnumerated => Some(KnownUsage::MonitorEnumerated(self.id)),
KnownUsagePage::VesaVirtualControls => {
vesa_virtual_controls::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::VesaVirtualControls)
}
KnownUsagePage::Power => power::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::Power),
KnownUsagePage::BatterySystem => battery_system::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::BatterySystem),
KnownUsagePage::BarcodeScanner => barcode_scanner::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::BarcodeScanner),
KnownUsagePage::Scales => scales::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::Scales),
KnownUsagePage::MagneticStripeReader => {
magnetic_stripe_reader::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::MagneticStripeReader)
}
KnownUsagePage::CameraControl => camera_control::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::CameraControl),
KnownUsagePage::Arcade => arcade::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::Arcade),
KnownUsagePage::GamingDevice => Some(KnownUsage::GamingDevice(self.id)),
KnownUsagePage::FidoAlliance => fido_alliance::KnownUsage::try_from(self.id)
.ok()
.map(KnownUsage::FidoAlliance),
}
}
}
#[derive(Clone, PartialEq)]
pub enum Usage {
Known(KnownUsage),
Unknown(u16),
}
impl Usage {
pub fn new(page: UsagePage, id: u16) -> Self {
match ExtendedUsage::new(page, id).get_known() {
Some(known) => Usage::Known(known),
None => Usage::Unknown(id),
}
}
pub fn without_page(id: u16) -> Self {
Usage::Unknown(id)
}
}
#[expect(missing_docs)]
#[derive(Clone, PartialEq)]
pub enum KnownUsage {
GenericDesktop(generic_desktop::KnownUsage),
SimulationControls(simulation_controls::KnownUsage),
VrControls(vr_controls::KnownUsage),
SportControls(sport_controls::KnownUsage),
GameControls(game_controls::KnownUsage),
GenericDeviceControls(generic_device_controls::KnownUsage),
KeyboardKeypad(keyboard_keypad::KnownUsage),
Led(led_page::KnownUsage),
Button(u16),
Ordinal(u16),
TelephonyDevice(telephony_device::KnownUsage),
Consumer(consumer::KnownUsage),
Digitizers(digitizers::KnownUsage),
Haptics(haptics::KnownUsage),
PhysicalInputDevice(physical_input_device::KnownUsage),
Unicode(u16),
Soc(soc::KnownUsage),
EyeAndHeadTrackers(eye_head_trackers::KnownUsage),
AuxiliaryDisplay(auxiliary_display::KnownUsage),
Sensors(sensors::KnownUsage),
MedicalInstrument(medical_instrument::KnownUsage),
BrailleDisplay(braille_display::KnownUsage),
LightingAndIllumination(lighting_illumination::KnownUsage),
Monitor(monitor::KnownUsage),
MonitorEnumerated(u16),
VesaVirtualControls(vesa_virtual_controls::KnownUsage),
Power(power::KnownUsage),
BatterySystem(battery_system::KnownUsage),
BarcodeScanner(barcode_scanner::KnownUsage),
Scales(scales::KnownUsage),
MagneticStripeReader(magnetic_stripe_reader::KnownUsage),
CameraControl(camera_control::KnownUsage),
Arcade(arcade::KnownUsage),
GamingDevice(u16),
FidoAlliance(fido_alliance::KnownUsage),
}
#[cfg(feature = "std")]
mod std_impls {
use std::fmt::{self, Debug, Display};
use super::*;
impl Debug for ExtendedUsage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut debug_struct = f.debug_struct("Usage");
debug_struct.field("page", &self.page);
if let Some(known) = self.get_known() {
debug_struct.field("id", &known);
} else {
debug_struct.field("id", &format_args!("{:#04x}", self.id));
}
debug_struct.finish()
}
}
impl Debug for Usage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut debug_struct = f.debug_struct("Usage");
match self {
Usage::Known(usage) => {
debug_struct.field("id", &usage);
}
Usage::Unknown(id) => {
debug_struct.field("id", &id);
}
}
debug_struct.finish()
}
}
impl Debug for KnownUsage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Button(value)
| Self::Ordinal(value)
| Self::Unicode(value)
| Self::MonitorEnumerated(value)
| Self::GamingDevice(value) => {
Debug::fmt(&value, f)
}
Self::GenericDesktop(value) => value.fmt(f),
Self::SimulationControls(value) => value.fmt(f),
Self::VrControls(value) => value.fmt(f),
Self::SportControls(value) => value.fmt(f),
Self::GameControls(value) => value.fmt(f),
Self::GenericDeviceControls(value) => value.fmt(f),
Self::KeyboardKeypad(value) => value.fmt(f),
Self::Led(value) => value.fmt(f),
Self::TelephonyDevice(value) => value.fmt(f),
Self::Consumer(value) => value.fmt(f),
Self::Digitizers(value) => value.fmt(f),
Self::Haptics(value) => value.fmt(f),
Self::PhysicalInputDevice(value) => value.fmt(f),
Self::Soc(value) => value.fmt(f),
Self::EyeAndHeadTrackers(value) => value.fmt(f),
Self::AuxiliaryDisplay(value) => value.fmt(f),
Self::Sensors(value) => value.fmt(f),
Self::MedicalInstrument(value) => value.fmt(f),
Self::BrailleDisplay(value) => value.fmt(f),
Self::LightingAndIllumination(value) => value.fmt(f),
Self::Monitor(value) => value.fmt(f),
Self::VesaVirtualControls(value) => value.fmt(f),
Self::Power(value) => value.fmt(f),
Self::BatterySystem(value) => value.fmt(f),
Self::BarcodeScanner(value) => value.fmt(f),
Self::Scales(value) => value.fmt(f),
Self::MagneticStripeReader(value) => value.fmt(f),
Self::CameraControl(value) => value.fmt(f),
Self::Arcade(value) => value.fmt(f),
Self::FidoAlliance(value) => value.fmt(f),
}
}
}
impl Display for KnownUsage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Button(value)
| Self::Ordinal(value)
| Self::Unicode(value)
| Self::MonitorEnumerated(value)
| Self::GamingDevice(value) => {
Display::fmt(&value, f)
}
Self::GenericDesktop(value) => value.fmt(f),
Self::SimulationControls(value) => value.fmt(f),
Self::VrControls(value) => value.fmt(f),
Self::SportControls(value) => value.fmt(f),
Self::GameControls(value) => value.fmt(f),
Self::GenericDeviceControls(value) => value.fmt(f),
Self::KeyboardKeypad(value) => value.fmt(f),
Self::Led(value) => value.fmt(f),
Self::TelephonyDevice(value) => value.fmt(f),
Self::Consumer(value) => value.fmt(f),
Self::Digitizers(value) => value.fmt(f),
Self::Haptics(value) => value.fmt(f),
Self::PhysicalInputDevice(value) => value.fmt(f),
Self::Soc(value) => value.fmt(f),
Self::EyeAndHeadTrackers(value) => value.fmt(f),
Self::AuxiliaryDisplay(value) => value.fmt(f),
Self::Sensors(value) => value.fmt(f),
Self::MedicalInstrument(value) => value.fmt(f),
Self::BrailleDisplay(value) => value.fmt(f),
Self::LightingAndIllumination(value) => value.fmt(f),
Self::Monitor(value) => value.fmt(f),
Self::VesaVirtualControls(value) => value.fmt(f),
Self::Power(value) => value.fmt(f),
Self::BatterySystem(value) => value.fmt(f),
Self::BarcodeScanner(value) => value.fmt(f),
Self::Scales(value) => value.fmt(f),
Self::MagneticStripeReader(value) => value.fmt(f),
Self::CameraControl(value) => value.fmt(f),
Self::Arcade(value) => value.fmt(f),
Self::FidoAlliance(value) => value.fmt(f),
}
}
}
impl Display for Usage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Usage::Known(usage) => Display::fmt(&usage, f),
Usage::Unknown(id) => Display::fmt(&format_args!("{id:#04x}"), f),
}
}
}
}