1use std::fmt::{Display, Formatter};
4
5use lazy_static::lazy_static;
6
7use crate::{OperatorId, Preset};
9
10#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
19#[repr(u8)]
20pub enum Output {
21 Op1 = 0,
23 Op2,
24 Op3,
25 Op4,
26 Op5,
27 Op6,
28
29 Amplifier,
31}
32
33impl Output {
34 pub fn is_operator(&self) -> bool {
35 self != &Output::Amplifier
36 }
37
38 pub fn from(operator_id: OperatorId) -> Option<Output> {
39 use Output::*;
40 match operator_id {
41 0 => Some(Op1),
42 1 => Some(Op2),
43 2 => Some(Op3),
44 3 => Some(Op4),
45 4 => Some(Op5),
46 5 => Some(Op6),
47 _ => None,
48 }
49 }
50}
51
52impl Display for Output {
53 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54 use Output::*;
55 let msg = match self {
56 Op1 => "Operator 1",
57 Op2 => "Operator 2",
58 Op3 => "Operator 3",
59 Op4 => "Operator 4",
60 Op5 => "Operator 5",
61 Op6 => "Operator 6",
62 Amplifier => "Amplifier",
63 };
64 f.write_str(msg)
65 }
66}
67
68pub type AlgorithmId = usize;
69
70pub struct Algorithm {
72 routing_by_operator: [Vec<Output>; Preset::OPERATOR_COUNT],
73}
74
75impl Algorithm {
76 pub const fn new(operators: [Vec<Output>; Preset::OPERATOR_COUNT]) -> Self {
77 Self {
78 routing_by_operator: operators,
79 }
80 }
81
82 pub fn is_carrier(&self, operator_id: OperatorId) -> bool {
84 let routing = self.routing(operator_id);
85 routing == Some(&vec![Output::Amplifier])
86 }
87
88 pub fn is_feedback(&self, operator_id: OperatorId) -> bool {
90 let output = Output::from(operator_id);
91 let routing = self.routing(operator_id);
92 output
93 .and_then(|output| routing.map(|routing| routing.contains(&output)))
94 .unwrap_or_default()
95 }
96
97 pub fn routing(&self, operator_id: OperatorId) -> Option<&Vec<Output>> {
98 self.routing_by_operator.get(operator_id as usize)
99 }
100}
101
102lazy_static! {
103static ref ALGORITHMS: [Algorithm; Algorithms::COUNT] = {
104 use Output::*;
105 [
106 Algorithm::new( [
107 vec![Amplifier],
108 vec![Op1],
109 vec![Amplifier],
110 vec![Op3],
111 vec![Op4],
112 vec![Op5, Op6],
113 ]), Algorithm::new( [
115 vec![Amplifier],
116 vec![Op1, Op2],
117 vec![Amplifier],
118 vec![Op3],
119 vec![Op4],
120 vec![Op5],
121 ]),
122 Algorithm::new( [
123 vec![Amplifier],
124 vec![Op1],
125 vec![Op2],
126 vec![Amplifier],
127 vec![Op4],
128 vec![Op5, Op6],
129 ]),
130 Algorithm::new( [
131 vec![Amplifier],
132 vec![Op1],
133 vec![Op2],
134 vec![Amplifier],
135 vec![Op4],
136 vec![Op5, Amplifier],
137 ]),
138 Algorithm::new( [
139 vec![Amplifier],
140 vec![Op1],
141 vec![Amplifier],
142 vec![Op3],
143 vec![Amplifier],
144 vec![Op5, Op6],
145 ]), Algorithm::new( [
147 vec![Amplifier],
148 vec![Op1],
149 vec![Amplifier],
150 vec![Op3],
151 vec![Amplifier],
152 vec![Op5, Amplifier],
153 ]),
154Algorithm::new( [
155 vec![Amplifier],
156 vec![Op1],
157 vec![Amplifier],
158 vec![Op3],
159 vec![Op3],
160 vec![Op5, Op6],
161 ]),
162Algorithm::new( [
163 vec![Amplifier],
164 vec![Op1],
165 vec![Amplifier],
166 vec![Op3, Op4],
167 vec![Op3],
168 vec![Op5],
169 ]),
170Algorithm::new( [
171 vec![Amplifier],
172 vec![Op1, Op2],
173 vec![Amplifier],
174 vec![Op3],
175 vec![Op3],
176 vec![Op5],
177 ]),
178Algorithm::new( [
179 vec![Amplifier],
180 vec![Op1],
181 vec![Op2, Op3],
182 vec![Amplifier],
183 vec![Op4],
184 vec![Op4],
185 ]), Algorithm::new( [
187 vec![Amplifier],
188 vec![Op1],
189 vec![Op2],
190 vec![Amplifier],
191 vec![Op4],
192 vec![Op4, Op6],
193 ]),
194Algorithm::new( [
195 vec![Amplifier],
196 vec![Op1, Op2],
197 vec![Amplifier],
198 vec![Op3],
199 vec![Op3],
200 vec![Op3],
201 ]),
202Algorithm::new( [
203 vec![Amplifier],
204 vec![Op1],
205 vec![Amplifier],
206 vec![Op3],
207 vec![Op3],
208 vec![Op3, Op6],
209 ]),
210Algorithm::new( [
211 vec![Amplifier],
212 vec![Op1],
213 vec![Amplifier],
214 vec![Op3],
215 vec![Op4],
216 vec![Op4, Op6],
217 ]),
218Algorithm::new( [
219 vec![Amplifier],
220 vec![Op1, Op2],
221 vec![Amplifier],
222 vec![Op3],
223 vec![Op4],
224 vec![Op4],
225 ]), Algorithm::new( [
227 vec![Amplifier],
228 vec![Op1],
229 vec![Op1],
230 vec![Op3],
231 vec![Op1],
232 vec![Op5, Op6],
233 ]),
234Algorithm::new( [
235 vec![Amplifier],
236 vec![Op1, Op2],
237 vec![Op1],
238 vec![Op3],
239 vec![Op1],
240 vec![Op5],
241 ]),
242Algorithm::new( [
243 vec![Amplifier],
244 vec![Op1],
245 vec![Op1, Op3],
246 vec![Op1],
247 vec![Op4],
248 vec![Op5],
249 ]),
250Algorithm::new( [
251 vec![Amplifier],
252 vec![Op1],
253 vec![Op2],
254 vec![Amplifier],
255 vec![Amplifier],
256 vec![Op4, Op5, Op6],
257 ]),
258Algorithm::new( [
259 vec![Amplifier],
260 vec![Amplifier],
261 vec![Op1, Op2, Op3],
262 vec![Amplifier],
263 vec![Op4],
264 vec![Op4],
265 ]), Algorithm::new( [
267 vec![Amplifier],
268 vec![Amplifier],
269 vec![Op1, Op2, Op3],
270 vec![Amplifier],
271 vec![Amplifier],
272 vec![Op4, Op5],
273 ]),
274Algorithm::new( [
275 vec![Amplifier],
276 vec![Op1],
277 vec![Amplifier],
278 vec![Amplifier],
279 vec![Amplifier],
280 vec![Op3, Op4, Op5, Op6],
281 ]),
282Algorithm::new( [
283 vec![Amplifier],
284 vec![Amplifier],
285 vec![Op2],
286 vec![Amplifier],
287 vec![Amplifier],
288 vec![Op4, Op5, Op6],
289 ]),
290Algorithm::new( [
291 vec![Amplifier],
292 vec![Amplifier],
293 vec![Amplifier],
294 vec![Amplifier],
295 vec![Amplifier],
296 vec![Op3, Op4, Op5, Op6],
297 ]),
298Algorithm::new( [
299 vec![Amplifier],
300 vec![Amplifier],
301 vec![Amplifier],
302 vec![Amplifier],
303 vec![Amplifier],
304 vec![Op4, Op5, Op6],
305 ]), Algorithm::new( [
307 vec![Amplifier],
308 vec![Amplifier],
309 vec![Op2],
310 vec![Amplifier],
311 vec![Op4],
312 vec![Op4, Op6],
313 ]),
314Algorithm::new( [
315 vec![Amplifier],
316 vec![Amplifier],
317 vec![Op2, Op3],
318 vec![Amplifier],
319 vec![Op4],
320 vec![Op4],
321 ]),
322Algorithm::new( [
323 vec![Amplifier],
324 vec![Op1],
325 vec![Amplifier],
326 vec![Op3],
327 vec![Op4, Op5],
328 vec![Amplifier],
329 ]),
330Algorithm::new( [
331 vec![Amplifier],
332 vec![Amplifier],
333 vec![Amplifier],
334 vec![Op3],
335 vec![Amplifier],
336 vec![Op5, Op6],
337 ]),
338Algorithm::new( [
339 vec![Amplifier],
340 vec![Amplifier],
341 vec![Amplifier],
342 vec![Op3],
343 vec![Op4, Op5],
344 vec![Amplifier],
345 ]), Algorithm::new( [
347 vec![Amplifier],
348 vec![Amplifier],
349 vec![Amplifier],
350 vec![Amplifier],
351 vec![Amplifier],
352 vec![Op5, Op6],
353 ]),
354Algorithm::new( [
355 vec![Amplifier],
356 vec![Amplifier],
357 vec![Amplifier],
358 vec![Amplifier],
359 vec![Amplifier],
360 vec![Amplifier, Op6],
361 ]), ]
363};
364}
365
366pub struct Algorithms;
367
368impl Algorithms {
369 const COUNT: usize = 32;
370
371 pub fn all() -> &'static [Algorithm; Algorithms::COUNT] {
372 &ALGORITHMS
373 }
374
375 pub fn get(id: AlgorithmId) -> Option<&'static Algorithm> {
376 ALGORITHMS.get(id)
377 }
378}
379
380#[cfg(test)]
381mod tests {
382 use std::collections::HashSet;
383
384 use super::*;
385
386 #[test]
387 fn carrier() {
388 let algorithm = Algorithms::get(0).unwrap();
389 assert!(algorithm.is_carrier(0));
390 assert!(!algorithm.is_carrier(1));
391 assert!(algorithm.is_carrier(2));
392 assert!(!algorithm.is_carrier(3));
393 assert!(!algorithm.is_carrier(5));
394 assert!(!algorithm.is_carrier(6));
395 }
396
397 #[test]
398 fn feedback() {
399 let algorithm = Algorithms::get(0).unwrap();
400 assert!(!algorithm.is_feedback(0));
401 assert!(algorithm.is_feedback(5));
402 }
403
404 #[test]
405 fn routing() {
406 for (algorithm_index, algorithm) in Algorithms::all().iter().enumerate() {
408 for operator_id in 0..ALGORITHMS[0].routing_by_operator.len() {
409 let routing = algorithm
410 .routing(operator_id as OperatorId)
411 .expect("every operator has a routing");
412 let unique: HashSet<&Output> = routing.into_iter().collect();
413 assert_eq!(
414 routing.len(),
415 unique.len(),
416 "Algorithm index {algorithm_index} contains duplicates"
417 );
418 assert!(
419 !routing.is_empty(),
420 "Algorithm index {algorithm_index} does not have an output for operator ID {operator_id}"
421 );
422 }
423 }
424 }
425}