1use core::{
16 cmp::Ordering,
17 fmt::{self, Debug},
18};
19
20#[derive(Debug)]
23pub struct TapData {
24 pub offset: u16,
26 pub back: u16,
28 pub group: usize,
30 pub combo: u8,
32 pub skip: u8,
34}
35
36impl PartialEq for TapData {
37 fn eq(&self, other: &Self) -> bool {
38 self.offset == other.offset && self.back == other.back && self.group == other.group
39 }
40}
41
42impl PartialOrd for TapData {
43 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
44 match self.group.partial_cmp(&other.group) {
45 Some(Ordering::Equal) => {}
46 ord => return ord,
47 }
48 match self.offset.partial_cmp(&other.offset) {
49 Some(Ordering::Equal) => {}
50 ord => return ord,
51 }
52 self.back.partial_cmp(&other.back)
53 }
54}
55
56#[derive(Debug)]
57pub struct TapSet<'a> {
58 pub taps: &'a [TapData],
59 pub combo_taps: &'a [u16],
60 pub combo_begin: &'a [u16],
61 pub group_begin: &'a [usize],
62 pub combos_count: usize,
63 pub reg_count: usize,
64 pub tot_combo_backs: usize,
65 pub group_names: &'a [&'a str],
66}
67
68impl TapSet<'_> {
69 pub fn num_groups(&self) -> usize {
70 self.group_names.len()
71 }
72
73 pub fn tap_size(&self) -> usize {
74 self.group_begin[self.num_groups()]
75 }
76
77 pub fn taps(&self) -> TapIter {
78 TapIter {
79 data: self.taps,
80 cursor: 0,
81 end: self.group_begin[self.num_groups()],
82 }
83 }
84
85 pub fn regs(&self) -> RegisterIter {
86 RegisterIter {
87 data: self.taps,
88 cursor: 0,
89 end: self.group_begin[self.num_groups()],
90 }
91 }
92
93 pub fn group_taps(&self, group_id: usize) -> TapIter {
94 TapIter {
95 data: self.taps,
96 cursor: self.group_begin[group_id],
97 end: self.group_begin[group_id + 1],
98 }
99 }
100
101 pub fn group_regs(&self, group_id: usize) -> RegisterIter {
102 RegisterIter {
103 data: self.taps,
104 cursor: self.group_begin[group_id],
105 end: self.group_begin[group_id + 1],
106 }
107 }
108
109 pub fn group_size(&self, group_id: usize) -> usize {
110 let idx = self.group_begin[group_id + 1] - 1;
111 let last = self.taps[idx].offset as usize;
112 last + 1
113 }
114
115 pub fn group_name(&self, group_id: usize) -> &str {
116 self.group_names[group_id]
117 }
118
119 pub fn combos_size(&self) -> usize {
120 self.combos_count
121 }
122
123 pub fn reg_count(&self) -> usize {
124 self.reg_count
125 }
126
127 pub fn combos(&self) -> ComboIter {
128 ComboIter {
129 data: ComboData {
130 taps: self.combo_taps,
131 offsets: self.combo_begin,
132 },
133 id: 0,
134 end: self.combos_count,
135 }
136 }
137
138 pub fn get_combo(&self, id: usize) -> ComboRef {
139 ComboRef {
140 data: ComboData {
141 taps: self.combo_taps,
142 offsets: self.combo_begin,
143 },
144 id,
145 }
146 }
147}
148
149pub struct RegisterRef<'a> {
150 data: &'a [TapData],
151 cursor: usize,
152}
153
154impl RegisterRef<'_> {
155 pub fn group(&self) -> usize {
156 self.data[self.cursor].group
157 }
158
159 pub fn offset(&self) -> usize {
160 self.data[self.cursor].offset as usize
161 }
162
163 pub fn combo_id(&self) -> usize {
164 self.data[self.cursor].combo as usize
165 }
166
167 pub fn size(&self) -> usize {
169 self.data[self.cursor].skip as usize
170 }
171
172 pub fn back(&self, i: usize) -> usize {
174 self.data[self.cursor + i].back as usize
175 }
176}
177
178impl Debug for RegisterRef<'_> {
179 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
180 f.debug_struct("RegisterRef")
181 .field("group", &self.group())
182 .field("offset", &self.offset())
183 .field("combo_id", &self.combo_id())
184 .field("size", &self.size())
185 .finish()
186 }
187}
188
189impl<'a> IntoIterator for RegisterRef<'a> {
190 type Item = TapRef<'a>;
191 type IntoIter = TapIter<'a>;
192
193 fn into_iter(self) -> Self::IntoIter {
194 TapIter {
195 data: self.data,
196 cursor: self.cursor,
197 end: self.cursor + self.size(),
198 }
199 }
200}
201
202pub struct RegisterIter<'a> {
203 data: &'a [TapData],
204 cursor: usize,
205 end: usize,
206}
207
208impl<'a> Iterator for RegisterIter<'a> {
209 type Item = RegisterRef<'a>;
210
211 fn next(&mut self) -> Option<Self::Item> {
212 let cursor = self.cursor;
213 if cursor >= self.data.len() {
214 return None;
215 }
216 let next = cursor + self.data[cursor].skip as usize;
217 if next > self.end {
218 return None;
219 }
220 self.cursor = next;
221 Some(RegisterRef {
222 data: self.data,
223 cursor,
224 })
225 }
226}
227
228pub struct TapRef<'a> {
229 data: &'a TapData,
230}
231
232impl TapRef<'_> {
233 pub fn group(&self) -> usize {
234 self.data.group
235 }
236
237 pub fn offset(&self) -> usize {
238 self.data.offset as usize
239 }
240
241 pub fn back(&self) -> usize {
242 self.data.back as usize
243 }
244
245 pub fn combo_id(&self) -> usize {
246 self.data.combo as usize
247 }
248}
249
250impl Debug for TapRef<'_> {
251 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
252 f.debug_struct("TapRef")
253 .field("group", &self.group())
254 .field("offset", &self.offset())
255 .field("back", &self.back())
256 .field("combo_id", &self.combo_id())
257 .finish()
258 }
259}
260
261pub struct TapIter<'a> {
262 data: &'a [TapData],
263 cursor: usize,
264 end: usize,
265}
266
267impl<'a> Iterator for TapIter<'a> {
268 type Item = TapRef<'a>;
269
270 fn next(&mut self) -> Option<Self::Item> {
271 let cursor = self.cursor;
272 let next = self.cursor + 1;
273 if next > self.end {
274 return None;
275 }
276 self.cursor = next;
277 Some(TapRef {
278 data: &self.data[cursor],
279 })
280 }
281}
282
283#[derive(Clone)]
289pub struct ComboData<'a> {
290 taps: &'a [u16],
291 offsets: &'a [u16],
292}
293
294pub struct ComboRef<'a> {
295 data: ComboData<'a>,
296 id: usize,
297}
298
299impl ComboRef<'_> {
300 pub fn id(&self) -> usize {
301 self.id
302 }
303
304 pub fn size(&self) -> usize {
305 self.next_offset() - self.self_offset()
306 }
307
308 pub fn slice(&self) -> &[u16] {
309 &self.data.taps[self.self_offset()..self.next_offset()]
310 }
311
312 fn self_offset(&self) -> usize {
313 self.data.offsets[self.id] as usize
314 }
315
316 fn next_offset(&self) -> usize {
317 self.data.offsets[self.id + 1] as usize
318 }
319}
320
321pub struct ComboIter<'a> {
322 data: ComboData<'a>,
323 id: usize,
324 end: usize,
325}
326
327impl<'a> Iterator for ComboIter<'a> {
328 type Item = ComboRef<'a>;
329
330 fn next(&mut self) -> Option<Self::Item> {
331 let id = self.id;
332 let next = self.id + 1;
333 if next > self.end {
334 return None;
335 }
336 self.id = next;
337 Some(ComboRef {
338 data: self.data.clone(),
339 id,
340 })
341 }
342}