Skip to main content

hid_types/id/
ident.rs

1//! A utility for handling well-known IDs and reserved values.
2
3/// A container that holds either a known variant, or an integer value with unknown meaning.
4#[derive(Clone, Copy, PartialEq)]
5pub enum Ident<T, Repr> {
6    /// A well-known Usage ID.
7    Known(T),
8    /// A reserved Usage ID.
9    ///
10    /// This can be used to identify vendor-specific types.
11    Reserved(Repr),
12}
13
14impl<T, Repr> From<T> for Ident<T, Repr> {
15    fn from(value: T) -> Self {
16        Self::Known(value)
17    }
18}
19
20#[cfg(feature = "std")]
21mod std_impls {
22    use super::*;
23
24    use std::fmt::{self, Debug, UpperHex};
25
26    impl<T, Repr> Debug for Ident<T, Repr>
27    where
28        T: Clone + Copy + PartialEq + Debug,
29        Repr: Clone + Copy + PartialEq + Debug + UpperHex,
30    {
31        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32            match self {
33                Self::Known(id) => id.fmt(f),
34                Self::Reserved(id) => f
35                    .debug_tuple("Reserved")
36                    .field(
37                        // FIXME: it would be nice to compute the number of leading zeroes
38                        // for the Repr type.
39                        &format_args!("{:#04X}", id),
40                    )
41                    .finish(),
42            }
43        }
44    }
45}
46
47impl<T, Repr> Ident<T, Repr>
48where
49    T: TryFrom<Repr>,
50    Repr: Clone + Copy,
51{
52    /// Try to decode a known identifier; if that fails store the raw number as a "reserved" value.
53    pub fn from_integer(value: Repr) -> Self {
54        match T::try_from(value) {
55            Ok(id) => Self::Known(id),
56            Err(_) => Self::Reserved(value),
57        }
58    }
59}
60
61impl<T> Ident<T, u8>
62where
63    T: Into<u8>,
64{
65    /// Convert the identifier to an integer.
66    pub fn to_integer(self) -> u8 {
67        match self {
68            Ident::Known(id) => id.into(),
69            Ident::Reserved(id) => id,
70        }
71    }
72}
73
74impl<T> Ident<T, u16>
75where
76    T: Into<u16>,
77{
78    /// Convert the identifier to an integer.
79    pub fn to_integer(self) -> u16 {
80        match self {
81            Ident::Known(id) => id.into(),
82            Ident::Reserved(id) => id,
83        }
84    }
85}