use crate::hid::{CollectionType, InputFlags, OutputFeatureFlags, Unit};
use crate::id::usage::UsagePage;
use crate::item::usage::{ExtendedUsage, Usage};
pub mod usage;
#[derive(Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum Item {
Long(LongItem),
Main(Main),
Global(Global),
Local(Local),
Reserved(u8),
}
impl Item {
#[cfg(feature = "std")]
pub fn type_note(&self) -> &'static str {
match self {
Item::Long(_) => "[long]",
Item::Main(_) => "[main]",
Item::Global(_) => "[global]",
Item::Local(_) => "[local]",
Item::Reserved(_) => "[reserved]",
}
}
}
#[derive(Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum Main {
Input(InputFlags),
Output(OutputFeatureFlags),
Feature(OutputFeatureFlags),
Collection(CollectionType),
EndCollection,
Reserved(u8),
}
#[derive(Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum Global {
UsagePage(UsagePage),
LogicalMinimum(i32),
LogicalMaximum(i32),
PhysicalMinimum(i32),
PhysicalMaximum(i32),
UnitExponent(i32),
Unit(Unit),
ReportSize(u32),
ReportId(u32),
ReportCount(u32),
Push,
Pop,
Reserved(u8),
}
#[derive(Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum Local {
Usage(Usage),
ExtendedUsage(ExtendedUsage),
UsageMinimum(u32),
UsageMaximum(u32),
DesignatorIndex(u32),
DesignatorMinimum(u32),
DesignatorMaximum(u32),
StringIndex(u32),
StringMinimum(u32),
StringMaximum(u32),
Delimiter(bool),
Reserved(u8),
}
#[derive(Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
#[expect(missing_docs)]
pub struct LongItem {
pub tag: u8,
#[cfg(feature = "std")]
pub data: std::vec::Vec<u8>,
}
#[cfg(feature = "std")]
mod std_impls {
use std::fmt::{self, Display};
use super::*;
impl Display for Item {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Item::Long(item) => {
write!(f, "tag {:#04x} [{} bytes]", item.tag, item.data.len())
}
Item::Main(item) => {
write!(f, "{item}")
}
Item::Global(item) => {
write!(f, "{item}")
}
Item::Local(item) => write!(f, "{item}"),
Item::Reserved(ty) => write!(f, "reserved type {ty}"),
}
}
}
impl Display for Main {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Main::Input(flags) => {
write!(f, "Input: {flags:?}")
}
Main::Output(flags) => {
write!(f, "Output: {flags:?}")
}
Main::Feature(flags) => {
write!(f, "Feature: {flags:?}")
}
Main::Collection(coll) => {
write!(f, "Collection: {coll:?}")
}
Main::EndCollection => {
write!(f, "EndCollection")
}
Main::Reserved(tag) => {
write!(f, "Reserved tag {tag:#04X}")
}
}
}
}
impl Display for Global {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Global::UsagePage(page) => {
write!(f, "Usage Page: {page:?}")
}
Global::LogicalMinimum(value) => write!(f, "Logical Minimum: {value}"),
Global::LogicalMaximum(value) => write!(f, "Logical Maximum: {value}"),
Global::PhysicalMinimum(value) => write!(f, "Physical Minimum: {value}"),
Global::PhysicalMaximum(value) => write!(f, "Physical Maximum: {value}"),
Global::UnitExponent(value) => write!(f, "Unit Exponent: {value}"),
Global::Unit(unit) => write!(f, "Unit: {unit:?}"),
Global::Push => write!(f, "Push"),
Global::Pop => write!(f, "Pop"),
Global::Reserved(tag) => write!(f, "Reserved tag {tag:#04X}"),
Global::ReportSize(value) => write!(f, "Report Size: {value}"),
Global::ReportId(value) => write!(f, "Report ID: {value}"),
Global::ReportCount(value) => write!(f, "Report Count: {value}"),
}
}
}
impl Display for Local {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Local::Usage(usage) => {
write!(f, "Usage: {usage}")
}
Local::ExtendedUsage(extended_usage) => {
write!(f, "Extended Usage: {extended_usage:?}")
}
Local::UsageMinimum(value) => {
write!(f, "Usage Minimum: {value}")
}
Local::UsageMaximum(value) => {
write!(f, "Usage Maximum: {value}")
}
Local::DesignatorIndex(value) => write!(f, "Designator Index: {value}"),
Local::DesignatorMinimum(value) => write!(f, "Designator Minimum: {value}"),
Local::DesignatorMaximum(value) => write!(f, "Designator Maximum: {value}"),
Local::StringIndex(value) => write!(f, "String Index: {value}"),
Local::StringMinimum(value) => write!(f, "String Minimum: {value}"),
Local::StringMaximum(value) => write!(f, "String Maximum: {value}"),
Local::Delimiter(value) => write!(f, "Delimiter: {value}"),
Local::Reserved(tag) => write!(f, "Reserved tag {tag:#04X}"),
}
}
}
}