hid-types 0.1.1

Rust types for working with USB HID report descriptors
Documentation
//! A utility for handling well-known IDs and reserved values.

/// A container that holds either a known variant, or an integer value with unknown meaning.
#[derive(Clone, Copy, PartialEq)]
pub enum Ident<T, Repr> {
    /// A well-known Usage ID.
    Known(T),
    /// A reserved Usage ID.
    ///
    /// This can be used to identify vendor-specific types.
    Reserved(Repr),
}

impl<T, Repr> From<T> for Ident<T, Repr> {
    fn from(value: T) -> Self {
        Self::Known(value)
    }
}

#[cfg(feature = "std")]
mod std_impls {
    use super::*;

    use std::fmt::{self, Debug, UpperHex};

    impl<T, Repr> Debug for Ident<T, Repr>
    where
        T: Clone + Copy + PartialEq + Debug,
        Repr: Clone + Copy + PartialEq + Debug + UpperHex,
    {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            match self {
                Self::Known(id) => id.fmt(f),
                Self::Reserved(id) => f
                    .debug_tuple("Reserved")
                    .field(
                        // FIXME: it would be nice to compute the number of leading zeroes
                        // for the Repr type.
                        &format_args!("{:#04X}", id),
                    )
                    .finish(),
            }
        }
    }
}

impl<T, Repr> Ident<T, Repr>
where
    T: TryFrom<Repr>,
    Repr: Clone + Copy,
{
    /// Try to decode a known identifier; if that fails store the raw number as a "reserved" value.
    pub fn from_integer(value: Repr) -> Self {
        match T::try_from(value) {
            Ok(id) => Self::Known(id),
            Err(_) => Self::Reserved(value),
        }
    }
}

impl<T> Ident<T, u8>
where
    T: Into<u8>,
{
    /// Convert the identifier to an integer.
    pub fn to_integer(self) -> u8 {
        match self {
            Ident::Known(id) => id.into(),
            Ident::Reserved(id) => id,
        }
    }
}

impl<T> Ident<T, u16>
where
    T: Into<u16>,
{
    /// Convert the identifier to an integer.
    pub fn to_integer(self) -> u16 {
        match self {
            Ident::Known(id) => id.into(),
            Ident::Reserved(id) => id,
        }
    }
}