1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
macro_rules! __impls_for_short_items {
($(#[$outer:meta])* $item:ident: $prefix:literal;) => {
$(#[$outer])*
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct $item([u8; 5]);
impl AsRef<[u8]> for $item {
fn as_ref(&self) -> &[u8] {
let end = crate::__data_size(self.0[0]) + 1;
&self.0[..end]
}
}
impl Default for $item {
fn default() -> Self {
Self([Self::PREFIX, 0, 0, 0, 0])
}
}
impl $item {
/// Prefix consists of tag(bit 7-4), type(bit 3-2) and size(bit 1-0).
/// The "size" part is set to `00` in this constant value.
pub const PREFIX: u8 = $prefix;
/// Create an item with prefix check.
pub fn new(raw: &[u8]) -> Result<Self, crate::HidError> {
if raw.is_empty() { return Err(crate::HidError::EmptyRawInput) };
if raw[0] & 0b1111_1100 != Self::PREFIX {
return Err(crate::HidError::PrefixNotMatch);
}
let expected = crate::__data_size(raw[0]);
if expected + 1 != raw.len() {
return Err(crate::HidError::DataSizeNotMatch {
expected,
provided: raw.len() - 1,
});
};
let mut storage = [0; 5];
storage[..raw.len()].copy_from_slice(raw);
Ok(Self(storage))
}
/// Create an item *WITHOUT* prefix check.
///
/// # Safety
///
/// Must ensure that the prefix part is correct.
pub unsafe fn new_unchecked(raw: &[u8]) -> Self {
let mut storage = [0; 5];
storage[..raw.len()].copy_from_slice(raw);
Self(storage)
}
/// Get prefix part of the item. Equivalent to `item.as_ref()[0]`.
pub fn prefix(&self) -> u8 {
self.0[0]
}
/// Get data part of the item. Equivalent to `&item.as_ref()[1..]`.
pub fn data(&self) -> &[u8] {
let end = crate::__data_size(self.0[0]) + 1;
&self.0[1..end]
}
/// Create an item with specific data.
///
/// *NOTE*: data size must be: 0, 1, 2 or 4.
pub fn new_with(data: &[u8]) -> Result<Self, crate::HidError> {
let mut item = Self([0; 5]);
item.0[0] = $prefix;
crate::__set_data_size(&mut item.0[0], data)?;
item.data_mut().copy_from_slice(data);
Ok(item)
}
/// Set data part of the item.
///
/// *NOTE*: data size must be: 0, 1, 2 or 4.
pub fn set_data(&mut self, data: &[u8]) -> Result<&mut Self, crate::HidError> {
crate::__set_data_size(&mut self.0[0], data)?;
self.data_mut().copy_from_slice(data);
Ok(self)
}
/// Get mutable data part of the item.
pub fn data_mut(&mut self) -> &mut [u8] {
let end = crate::__data_size(self.0[0]) + 1;
&mut self.0[1..end]
}
}
};
($(#[$outer:meta])* $item:ident: $prefix:literal; $($rest:tt)*) => {
__impls_for_short_items! { $(#[$outer])* $item: $prefix; }
__impls_for_short_items! { $($rest)* }
}
}
macro_rules! __matches_bit {
($field:expr, $pos:literal, $zero:literal, $one:literal) => {
match $field & (1 << $pos) {
0 => $zero,
_ => $one,
}
};
}
pub(crate) use __impls_for_short_items;
pub(crate) use __matches_bit;