use crate::Ident;
use crate::id::usage::*;
#[derive(Clone, Copy, PartialEq)]
pub struct ExtendedUsage {
pub page: UsagePage,
pub id: Usage,
}
impl ExtendedUsage {
pub fn new(page: UsagePage, id: u16) -> Self {
let id = Usage::new(page, id);
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);
let id = Usage::new(page, lsb);
Self { page, id }
}
pub fn to_integer(&self) -> u32 {
let page = self.page.to_integer();
let id = self.id.to_integer();
(page as u32) << 16 | (id as u32)
}
}
#[derive(Clone, Copy, PartialEq)]
pub enum Usage {
Known(KnownUsage),
Unknown(u16),
}
impl PartialOrd for Usage {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
let this = self.to_integer();
let other = other.to_integer();
this.partial_cmp(&other)
}
}
impl Usage {
pub fn new(page: UsagePage, id: u16) -> Self {
let usage = match page {
Ident::Known(known_page) => KnownUsage::from_page_and_id(known_page, id),
Ident::Reserved(_) => None,
};
match usage {
Some(known) => Usage::Known(known),
None => Usage::Unknown(id),
}
}
pub fn without_page(id: u16) -> Self {
Usage::Unknown(id)
}
pub fn to_integer(&self) -> u16 {
match self {
Usage::Known(known_usage) => known_usage.to_integer(),
Usage::Unknown(value) => *value,
}
}
pub fn successor(&self, page: UsagePage) -> Option<Self> {
let id = self.to_integer().checked_add(1)?;
Some(Usage::new(page, id))
}
}
#[expect(missing_docs)]
#[derive(Clone, Copy, PartialEq)]
#[non_exhaustive]
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),
}
impl KnownUsage {
pub fn from_page_and_id(page: KnownUsagePage, id: u16) -> Option<Self> {
match page {
KnownUsagePage::Undefined => None,
KnownUsagePage::GenericDesktop => generic_desktop::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::GenericDesktop),
KnownUsagePage::SimulationControls => simulation_controls::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::SimulationControls),
KnownUsagePage::VrControls => vr_controls::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::VrControls),
KnownUsagePage::SportControls => sport_controls::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::SportControls),
KnownUsagePage::GameControls => game_controls::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::GameControls),
KnownUsagePage::GenericDeviceControls => {
generic_device_controls::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::GenericDeviceControls)
}
KnownUsagePage::KeyboardKeypad => keyboard_keypad::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::KeyboardKeypad),
KnownUsagePage::Led => led_page::KnownUsage::try_from(id).ok().map(KnownUsage::Led),
KnownUsagePage::Button => Some(KnownUsage::Button(id)),
KnownUsagePage::Ordinal => Some(KnownUsage::Ordinal(id)),
KnownUsagePage::TelephonyDevice => telephony_device::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::TelephonyDevice),
KnownUsagePage::Consumer => consumer::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::Consumer),
KnownUsagePage::Digitizers => digitizers::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::Digitizers),
KnownUsagePage::Haptics => haptics::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::Haptics),
KnownUsagePage::PhysicalInputDevice => physical_input_device::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::PhysicalInputDevice),
KnownUsagePage::Unicode => Some(KnownUsage::Unicode(id)),
KnownUsagePage::Soc => soc::KnownUsage::try_from(id).ok().map(KnownUsage::Soc),
KnownUsagePage::EyeAndHeadTrackers => eye_head_trackers::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::EyeAndHeadTrackers),
KnownUsagePage::AuxiliaryDisplay => auxiliary_display::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::AuxiliaryDisplay),
KnownUsagePage::Sensors => sensors::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::Sensors),
KnownUsagePage::MedicalInstrument => medical_instrument::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::MedicalInstrument),
KnownUsagePage::BrailleDisplay => braille_display::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::BrailleDisplay),
KnownUsagePage::LightingAndIllumination => {
lighting_illumination::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::LightingAndIllumination)
}
KnownUsagePage::Monitor => monitor::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::Monitor),
KnownUsagePage::MonitorEnumerated => Some(KnownUsage::MonitorEnumerated(id)),
KnownUsagePage::VesaVirtualControls => vesa_virtual_controls::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::VesaVirtualControls),
KnownUsagePage::Power => power::KnownUsage::try_from(id).ok().map(KnownUsage::Power),
KnownUsagePage::BatterySystem => battery_system::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::BatterySystem),
KnownUsagePage::BarcodeScanner => barcode_scanner::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::BarcodeScanner),
KnownUsagePage::Scales => scales::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::Scales),
KnownUsagePage::MagneticStripeReader => {
magnetic_stripe_reader::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::MagneticStripeReader)
}
KnownUsagePage::CameraControl => camera_control::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::CameraControl),
KnownUsagePage::Arcade => arcade::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::Arcade),
KnownUsagePage::GamingDevice => Some(KnownUsage::GamingDevice(id)),
KnownUsagePage::FidoAlliance => fido_alliance::KnownUsage::try_from(id)
.ok()
.map(KnownUsage::FidoAlliance),
}
}
fn to_integer(self) -> u16 {
match self {
KnownUsage::GenericDesktop(usage) => usage.into(),
KnownUsage::SimulationControls(usage) => usage.into(),
KnownUsage::VrControls(usage) => usage.into(),
KnownUsage::SportControls(usage) => usage.into(),
KnownUsage::GameControls(usage) => usage.into(),
KnownUsage::GenericDeviceControls(usage) => usage.into(),
KnownUsage::KeyboardKeypad(usage) => usage.into(),
KnownUsage::Led(usage) => usage.into(),
KnownUsage::Button(usage) => usage,
KnownUsage::Ordinal(usage) => usage,
KnownUsage::TelephonyDevice(usage) => usage.into(),
KnownUsage::Consumer(usage) => usage.into(),
KnownUsage::Digitizers(usage) => usage.into(),
KnownUsage::Haptics(usage) => usage.into(),
KnownUsage::PhysicalInputDevice(usage) => usage.into(),
KnownUsage::Unicode(usage) => usage,
KnownUsage::Soc(usage) => usage.into(),
KnownUsage::EyeAndHeadTrackers(usage) => usage.into(),
KnownUsage::AuxiliaryDisplay(usage) => usage.into(),
KnownUsage::Sensors(usage) => usage.into(),
KnownUsage::MedicalInstrument(usage) => usage.into(),
KnownUsage::BrailleDisplay(usage) => usage.into(),
KnownUsage::LightingAndIllumination(usage) => usage.into(),
KnownUsage::Monitor(usage) => usage.into(),
KnownUsage::MonitorEnumerated(usage) => usage,
KnownUsage::VesaVirtualControls(usage) => usage.into(),
KnownUsage::Power(usage) => usage.into(),
KnownUsage::BatterySystem(usage) => usage.into(),
KnownUsage::BarcodeScanner(usage) => usage.into(),
KnownUsage::Scales(usage) => usage.into(),
KnownUsage::MagneticStripeReader(usage) => usage.into(),
KnownUsage::CameraControl(usage) => usage.into(),
KnownUsage::Arcade(usage) => usage.into(),
KnownUsage::GamingDevice(usage) => usage,
KnownUsage::FidoAlliance(usage) => usage.into(),
}
}
}
#[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);
debug_struct.field("id", &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),
}
}
}
}