1use hid_types::encoding::{TagTypeSize, TypeBits, encode_signed, encode_unsigned};
2use hid_types::id::{GlobalItem, IntoTagType, LocalItem, MainItem};
3use hid_types::item::{Global, Item, Local, LongItem, Main};
4
5use crate::DescriptorBytes;
6
7pub trait EncodeItem {
9 fn encode(&self) -> DescriptorBytes;
11}
12
13impl EncodeItem for LongItem {
14 fn encode(&self) -> DescriptorBytes {
15 long_encode(self.tag, &self.data)
16 }
17}
18
19impl EncodeItem for Main {
20 fn encode(&self) -> DescriptorBytes {
21 match self {
22 Main::Input(input_flags) => {
23 let data: u32 = input_flags.0.into();
24 short_encode_unsigned(MainItem::Input, &data.to_le_bytes())
25 }
26 Main::Output(output_flags) => {
27 let data: u32 = output_flags.0.into();
28 short_encode_unsigned(MainItem::Output, &data.to_le_bytes())
29 }
30 Main::Feature(feature_flags) => {
31 let data: u32 = feature_flags.0.into();
32 short_encode_unsigned(MainItem::Feature, &data.to_le_bytes())
33 }
34 Main::Collection(ty) => {
35 let data: u8 = ty.to_integer();
36 short_encode_unsigned(MainItem::Collection, &data.to_le_bytes())
37 }
38 Main::EndCollection => short_encode_unsigned(MainItem::EndCollection, &[]),
39 Main::Reserved(tag, data) => reserved_encode(*tag, TypeBits::Main, *data),
40 }
41 }
42}
43
44impl EncodeItem for Global {
45 fn encode(&self) -> DescriptorBytes {
46 match self {
47 Global::UsagePage(usage_page) => {
48 let data = usage_page.to_integer().to_le_bytes();
49 short_encode_unsigned(GlobalItem::UsagePage, &data)
50 }
51 Global::LogicalMinimum(value) => {
52 short_encode_signed(GlobalItem::LogicalMinimum, &value.to_le_bytes())
53 }
54 Global::LogicalMaximum(value) => {
55 short_encode_signed(GlobalItem::LogicalMaximum, &value.to_le_bytes())
56 }
57 Global::PhysicalMinimum(value) => {
58 short_encode_signed(GlobalItem::PhysicalMinimum, &value.to_le_bytes())
59 }
60 Global::PhysicalMaximum(value) => {
61 short_encode_signed(GlobalItem::PhysicalMaximum, &value.to_le_bytes())
62 }
63 Global::UnitExponent(value) => {
64 short_encode_signed(GlobalItem::UnitExponent, &value.to_le_bytes())
65 }
66 Global::Unit(unit) => {
67 let data = unit.to_integer().to_le_bytes();
68 short_encode_unsigned(GlobalItem::Unit, &data)
69 }
70 Global::ReportSize(value) => {
71 short_encode_unsigned(GlobalItem::ReportSize, &value.to_le_bytes())
72 }
73 Global::ReportId(value) => {
74 short_encode_unsigned(GlobalItem::ReportId, &value.to_le_bytes())
75 }
76 Global::ReportCount(value) => {
77 short_encode_unsigned(GlobalItem::ReportCount, &value.to_le_bytes())
78 }
79 Global::Push => short_encode_unsigned(GlobalItem::Push, &[]),
80 Global::Pop => short_encode_unsigned(GlobalItem::Pop, &[]),
81 Global::Reserved(tag, data) => reserved_encode(*tag, TypeBits::Global, *data),
82 }
83 }
84}
85
86impl EncodeItem for Local {
87 fn encode(&self) -> DescriptorBytes {
88 match self {
89 Local::Usage(usage) => {
90 let data = usage.to_integer().to_le_bytes();
91 short_encode_unsigned(LocalItem::Usage, &data)
92 }
93 Local::ExtendedUsage(extended_usage) => {
94 let data = extended_usage.to_integer().to_le_bytes();
95 short_encode_unsigned(LocalItem::Usage, &data)
96 }
97 Local::UsageMinimum(value) => {
98 short_encode_unsigned(LocalItem::UsageMinimum, &value.to_le_bytes())
99 }
100 Local::UsageMaximum(value) => {
101 short_encode_unsigned(LocalItem::UsageMaximum, &value.to_le_bytes())
102 }
103 Local::DesignatorIndex(value) => {
104 short_encode_unsigned(LocalItem::DesignatorIndex, &value.to_le_bytes())
105 }
106 Local::DesignatorMinimum(value) => {
107 short_encode_unsigned(LocalItem::DesignatorMinimum, &value.to_le_bytes())
108 }
109 Local::DesignatorMaximum(value) => {
110 short_encode_unsigned(LocalItem::DesignatorMaximum, &value.to_le_bytes())
111 }
112 Local::StringIndex(value) => {
113 short_encode_unsigned(LocalItem::StringIndex, &value.to_le_bytes())
114 }
115 Local::StringMinimum(value) => {
116 short_encode_unsigned(LocalItem::StringMinimum, &value.to_le_bytes())
117 }
118 Local::StringMaximum(value) => {
119 short_encode_unsigned(LocalItem::StringMaximum, &value.to_le_bytes())
120 }
121 Local::Delimiter(value) => {
122 let data = u8::from(*value);
123 short_encode_unsigned(LocalItem::Delimiter, &data.to_le_bytes())
124 }
125 Local::Reserved(tag, data) => reserved_encode(*tag, TypeBits::Local, *data),
126 }
127 }
128}
129
130impl EncodeItem for Item {
131 fn encode(&self) -> DescriptorBytes {
132 match self {
133 Item::Long(long_item) => long_item.encode(),
134 Item::Main(main) => main.encode(),
135 Item::Global(global) => global.encode(),
136 Item::Local(local) => local.encode(),
137 Item::Reserved(tag, data) => reserved_encode(*tag, TypeBits::Reserved, *data),
138 }
139 }
140}
141
142fn long_encode(tag: u8, data: &[u8]) -> DescriptorBytes {
143 const LONG_TAG_BYTE: u8 = 0xFE;
145
146 let data_size: u8 = data
147 .len()
148 .try_into()
149 .expect("long encoding can only store 255 bytes");
150
151 [LONG_TAG_BYTE, data_size, tag]
152 .into_iter()
153 .chain(data.iter().copied())
154 .collect()
155}
156
157fn reserved_encode(tag: u8, ty: TypeBits, data: Option<i32>) -> DescriptorBytes {
158 let tts = TagTypeSize::new().with_tag(tag).with_ty(ty);
159
160 let data: &[u8] = match data {
161 None => &[],
162 Some(bytes) => &bytes.to_le_bytes(),
163 };
164
165 short_encode_signed(tts, data)
166}
167
168fn short_encode_unsigned<T: IntoTagType>(tag: T, data: &[u8]) -> DescriptorBytes {
169 let data = encode_unsigned(data);
170 let tag = TagTypeSize::from_tag(tag, data.len());
171
172 [tag.into_bits()]
173 .into_iter()
174 .chain(data.iter().copied())
175 .collect()
176}
177
178fn short_encode_signed<T: IntoTagType>(tag: T, data: &[u8]) -> DescriptorBytes {
179 let data = encode_signed(data);
180 let tag = TagTypeSize::from_tag(tag, data.len());
181
182 [tag.into_bits()]
183 .into_iter()
184 .chain(data.iter().copied())
185 .collect()
186}