1use ot_tools_io_derive::{
5    enum_try_from_i32_to_signed_types, enum_try_from_u32_to_unsigned_types, IntoSigneds,
6    IntoUnsigneds,
7};
8use serde::{Deserialize, Serialize};
9use std::fmt::Display;
10use thiserror::Error;
11
12#[derive(Debug, Error)]
14pub enum InvalidValueError {
15    #[error(
17        "Invalid time stretch value, only '0' (Off), '2' (Normal) and '3' (Beat) are supported values"
18    )]
19    TimeStretchMode,
20
21    #[error(
23        "Invalid loop mode value, only '0' (Off), '1' (Normal) and '2' (PingPong) are supported values"
24    )]
25    LoopMode,
26
27    #[error("Invalid trig quantization value")]
29    TrigQuantizationMode,
30
31    #[error("Invalid trig condition value")]
33    TrigCondition,
34
35    #[error("Invalid MIDI Channel value")]
37    MidiChannel,
38
39    #[error("Invalid slot type value, only 'FLEX' and 'STATIC' are supported values")]
41    SlotType,
42}
43
44#[derive(
47    PartialEq, Debug, Clone, Default, Serialize, Deserialize, Copy, Hash, Eq, IntoUnsigneds,
48)]
49#[repr(u8)]
50pub enum TimeStretchMode {
51    Off = 0,
53
54    #[default]
56    Normal = 2,
57
58    Beat = 3,
60}
61
62#[enum_try_from_u32_to_unsigned_types]
63impl TryFrom<u32> for TimeStretchMode {
64    type Error = InvalidValueError;
65    fn try_from(value: u32) -> Result<Self, Self::Error> {
66        match value {
67            0 => Ok(TimeStretchMode::Off),
68            2 => Ok(TimeStretchMode::Normal),
69            3 => Ok(TimeStretchMode::Beat),
70            _ => Err(InvalidValueError::TimeStretchMode),
71        }
72    }
73}
74
75#[cfg(test)]
76mod ot_time_stretch_mode {
77    mod value {
78        use crate::settings::TimeStretchMode;
79
80        #[test]
81        fn test_off_value() {
82            assert_eq!(TimeStretchMode::Off as u8, 0_u8);
83        }
84        #[test]
85        fn test_normal_value() {
86            assert_eq!(TimeStretchMode::Normal as u8, 2_u8);
87        }
88        #[test]
89        fn test_beat_value() {
90            assert_eq!(TimeStretchMode::Beat as u8, 3_u8);
91        }
92    }
93
94    mod from_value {
95        use crate::settings::TimeStretchMode;
96
97        #[test]
98        fn test_error() {
99            assert!(TimeStretchMode::try_from(&1_u8).is_err());
102            assert_eq!(TimeStretchMode::try_from(&1_u8).unwrap_err().to_string(),  "Invalid time stretch value, only '0' (Off), '2' (Normal) and '3' (Beat) are supported values");
103            for x in 4..u8::MAX {
104                assert!(TimeStretchMode::try_from(&x).is_err());
105                assert_eq!(TimeStretchMode::try_from(&x).unwrap_err().to_string(),  "Invalid time stretch value, only '0' (Off), '2' (Normal) and '3' (Beat) are supported values");
106            }
107        }
108        #[test]
109        fn test_off_from_value() {
110            assert_eq!(
111                TimeStretchMode::Off,
112                TimeStretchMode::try_from(&0_u8).unwrap()
113            );
114        }
115        #[test]
116        fn test_normal_from_value() {
117            assert_eq!(
118                TimeStretchMode::Normal,
119                TimeStretchMode::try_from(&2_u8).unwrap()
120            );
121        }
122        #[test]
123        fn test_beat_from_value() {
124            assert_eq!(
125                TimeStretchMode::Beat,
126                TimeStretchMode::try_from(&3_u8).unwrap()
127            );
128        }
129    }
130}
131
132#[derive(
135    PartialEq, Debug, Clone, Default, Serialize, Deserialize, Copy, Hash, Eq, IntoUnsigneds,
136)]
137#[repr(u8)]
138pub enum LoopMode {
139    #[default]
141    Off = 0,
142
143    Normal = 1,
145
146    PingPong = 2,
148}
149
150#[enum_try_from_u32_to_unsigned_types]
151impl TryFrom<u32> for LoopMode {
152    type Error = InvalidValueError;
153    fn try_from(value: u32) -> Result<Self, Self::Error> {
154        match value {
155            0 => Ok(LoopMode::Off),
156            1 => Ok(LoopMode::Normal),
157            2 => Ok(LoopMode::PingPong),
158            _ => Err(InvalidValueError::LoopMode),
159        }
160    }
161}
162
163#[cfg(test)]
164mod ot_loop_mode {
165
166    mod value {
167        use crate::settings::LoopMode;
168
169        #[test]
170        fn test_off_value() {
171            assert_eq!(LoopMode::Off as u8, 0_u8);
172        }
173        #[test]
174        fn test_normal_value() {
175            assert_eq!(LoopMode::Normal as u8, 1_u8);
176        }
177        #[test]
178        fn test_beat_value() {
179            assert_eq!(LoopMode::PingPong as u8, 2_u8);
180        }
181    }
182
183    mod from_value {
184        use crate::settings::LoopMode;
185
186        #[test]
187        fn test_error() {
188            for x in 3..u8::MAX {
189                assert!(LoopMode::try_from(&x).is_err());
190                assert_eq!(LoopMode::try_from(&x).unwrap_err().to_string(), "Invalid loop mode value, only '0' (Off), '1' (Normal) and '2' (PingPong) are supported values");
191            }
192        }
193        #[test]
194        fn test_off_from_value() {
195            assert_eq!(LoopMode::Off, LoopMode::try_from(&0_u8).unwrap());
196        }
197        #[test]
198        fn test_normal_from_value() {
199            assert_eq!(LoopMode::Normal, LoopMode::try_from(&1_u8).unwrap());
200        }
201        #[test]
202        fn test_beat_from_value() {
203            assert_eq!(LoopMode::PingPong, LoopMode::try_from(&2_u8).unwrap());
204        }
205    }
206}
207
208#[derive(
212    PartialEq, Debug, Clone, Default, Serialize, Deserialize, Copy, Hash, Eq, IntoUnsigneds,
213)]
214#[repr(u8)]
215pub enum TrigQuantizationMode {
216    #[default]
218    Direct = 255,
219
220    PatternLength = 0,
222
223    OneStep = 1,
225
226    TwoSteps = 2,
228
229    ThreeSteps = 3,
231
232    FourSteps = 4,
234
235    SixSteps = 5,
237
238    EightSteps = 6,
240
241    TwelveSteps = 7,
243
244    SixteenSteps = 8,
246
247    TwentyFourSteps = 9,
249
250    ThirtyTwoSteps = 10,
252
253    FortyEightSteps = 11,
255
256    SixtyFourSteps = 12,
258
259    NinetySixSteps = 13,
261
262    OneTwentyEightSteps = 14,
264
265    OneNinetyTwoSteps = 15,
267
268    TwoFiveSixSteps = 16,
270}
271
272#[enum_try_from_u32_to_unsigned_types]
273impl TryFrom<u32> for TrigQuantizationMode {
274    type Error = InvalidValueError;
275    fn try_from(value: u32) -> Result<Self, Self::Error> {
276        match value {
277            255 => Ok(TrigQuantizationMode::Direct),
278            0 => Ok(TrigQuantizationMode::PatternLength),
279            1 => Ok(TrigQuantizationMode::OneStep),
280            2 => Ok(TrigQuantizationMode::TwoSteps),
281            3 => Ok(TrigQuantizationMode::ThreeSteps),
282            4 => Ok(TrigQuantizationMode::FourSteps),
283            5 => Ok(TrigQuantizationMode::SixSteps),
284            6 => Ok(TrigQuantizationMode::EightSteps),
285            7 => Ok(TrigQuantizationMode::TwelveSteps),
286            8 => Ok(TrigQuantizationMode::SixteenSteps),
287            9 => Ok(TrigQuantizationMode::TwentyFourSteps),
288            10 => Ok(TrigQuantizationMode::ThirtyTwoSteps),
289            11 => Ok(TrigQuantizationMode::FortyEightSteps),
290            12 => Ok(TrigQuantizationMode::SixtyFourSteps),
291            13 => Ok(TrigQuantizationMode::NinetySixSteps),
292            14 => Ok(TrigQuantizationMode::OneTwentyEightSteps),
293            15 => Ok(TrigQuantizationMode::OneNinetyTwoSteps),
294            16 => Ok(TrigQuantizationMode::TwoFiveSixSteps),
295            _ => Err(InvalidValueError::TrigQuantizationMode),
296        }
297    }
298}
299
300#[cfg(test)]
301mod ot_trig_quantize_mode {
302
303    mod value {
304        use crate::settings::TrigQuantizationMode;
305
306        #[test]
307        fn test_direct() {
308            assert_eq!(TrigQuantizationMode::Direct as u8, 255);
309        }
310        #[test]
311        fn test_patternlen() {
312            assert_eq!(TrigQuantizationMode::PatternLength as u8, 0);
313        }
314        #[test]
315        fn test_1() {
316            assert_eq!(TrigQuantizationMode::OneStep as u8, 1);
317        }
318        #[test]
319        fn test_2() {
320            assert_eq!(TrigQuantizationMode::TwoSteps as u8, 2);
321        }
322        #[test]
323        fn test_3() {
324            assert_eq!(TrigQuantizationMode::ThreeSteps as u8, 3);
325        }
326        #[test]
327        fn test_4() {
328            assert_eq!(TrigQuantizationMode::FourSteps as u8, 4);
329        }
330        #[test]
331        fn test_6() {
332            assert_eq!(TrigQuantizationMode::SixSteps as u8, 5);
333        }
334        #[test]
335        fn test_8() {
336            assert_eq!(TrigQuantizationMode::EightSteps as u8, 6);
337        }
338        #[test]
339        fn test_12() {
340            assert_eq!(TrigQuantizationMode::TwelveSteps as u8, 7);
341        }
342        #[test]
343        fn test_16() {
344            assert_eq!(TrigQuantizationMode::SixteenSteps as u8, 8);
345        }
346        #[test]
347        fn test_24() {
348            assert_eq!(TrigQuantizationMode::TwentyFourSteps as u8, 9);
349        }
350        #[test]
351        fn test_32() {
352            assert_eq!(TrigQuantizationMode::ThirtyTwoSteps as u8, 10);
353        }
354        #[test]
355        fn test_48() {
356            assert_eq!(TrigQuantizationMode::FortyEightSteps as u8, 11);
357        }
358        #[test]
359        fn test_64() {
360            assert_eq!(TrigQuantizationMode::SixtyFourSteps as u8, 12);
361        }
362        #[test]
363        fn test_96() {
364            assert_eq!(TrigQuantizationMode::NinetySixSteps as u8, 13);
365        }
366        #[test]
367        fn test_128() {
368            assert_eq!(TrigQuantizationMode::OneTwentyEightSteps as u8, 14);
369        }
370        #[test]
371        fn test_192() {
372            assert_eq!(TrigQuantizationMode::OneNinetyTwoSteps as u8, 15);
373        }
374        #[test]
375        fn test_256() {
376            assert_eq!(TrigQuantizationMode::TwoFiveSixSteps as u8, 16);
377        }
378    }
379
380    mod from_value {
381        use crate::settings::TrigQuantizationMode;
382
383        #[test]
384        fn test_error() {
385            for i in 17..=254_u8 {
386                assert!(TrigQuantizationMode::try_from(i).is_err());
387                assert_eq!(
388                    TrigQuantizationMode::try_from(i).unwrap_err().to_string(),
389                    "Invalid trig quantization value"
390                );
391            }
392        }
393        #[test]
394        fn test_direct() {
395            assert_eq!(
396                TrigQuantizationMode::Direct,
397                TrigQuantizationMode::try_from(255_u8).unwrap()
398            );
399        }
400        #[test]
401        fn test_patternlen() {
402            assert_eq!(
403                TrigQuantizationMode::PatternLength,
404                TrigQuantizationMode::try_from(0_u8).unwrap()
405            );
406        }
407        #[test]
408        fn test_1() {
409            assert_eq!(
410                TrigQuantizationMode::OneStep,
411                TrigQuantizationMode::try_from(1_u8).unwrap()
412            );
413        }
414        #[test]
415        fn test_2() {
416            assert_eq!(
417                TrigQuantizationMode::TwoSteps,
418                TrigQuantizationMode::try_from(2_u8).unwrap()
419            );
420        }
421        #[test]
422        fn test_3() {
423            assert_eq!(
424                TrigQuantizationMode::ThreeSteps,
425                TrigQuantizationMode::try_from(3_u8).unwrap()
426            );
427        }
428        #[test]
429        fn test_4() {
430            assert_eq!(
431                TrigQuantizationMode::FourSteps,
432                TrigQuantizationMode::try_from(4_u8).unwrap()
433            );
434        }
435        #[test]
436        fn test_6() {
437            assert_eq!(
438                TrigQuantizationMode::SixSteps,
439                TrigQuantizationMode::try_from(5_u8).unwrap()
440            );
441        }
442        #[test]
443        fn test_8() {
444            assert_eq!(
445                TrigQuantizationMode::EightSteps,
446                TrigQuantizationMode::try_from(6_u8).unwrap()
447            );
448        }
449        #[test]
450        fn test_12() {
451            assert_eq!(
452                TrigQuantizationMode::TwelveSteps,
453                TrigQuantizationMode::try_from(7_u8).unwrap()
454            );
455        }
456        #[test]
457        fn test_16() {
458            assert_eq!(
459                TrigQuantizationMode::SixteenSteps,
460                TrigQuantizationMode::try_from(8_u8).unwrap()
461            );
462        }
463        #[test]
464        fn test_24() {
465            assert_eq!(
466                TrigQuantizationMode::TwentyFourSteps,
467                TrigQuantizationMode::try_from(9_u8).unwrap()
468            );
469        }
470        #[test]
471        fn test_32() {
472            assert_eq!(
473                TrigQuantizationMode::ThirtyTwoSteps,
474                TrigQuantizationMode::try_from(10_u8).unwrap()
475            );
476        }
477        #[test]
478        fn test_48() {
479            assert_eq!(
480                TrigQuantizationMode::FortyEightSteps,
481                TrigQuantizationMode::try_from(11_u8).unwrap()
482            );
483        }
484        #[test]
485        fn test_64() {
486            assert_eq!(
487                TrigQuantizationMode::SixtyFourSteps,
488                TrigQuantizationMode::try_from(12_u8).unwrap()
489            );
490        }
491        #[test]
492        fn test_96() {
493            assert_eq!(
494                TrigQuantizationMode::NinetySixSteps,
495                TrigQuantizationMode::try_from(13_u8).unwrap()
496            );
497        }
498        #[test]
499        fn test_128() {
500            assert_eq!(
501                TrigQuantizationMode::OneTwentyEightSteps,
502                TrigQuantizationMode::try_from(14_u8).unwrap()
503            );
504        }
505        #[test]
506        fn test_192() {
507            assert_eq!(
508                TrigQuantizationMode::OneNinetyTwoSteps,
509                TrigQuantizationMode::try_from(15_u8).unwrap()
510            );
511        }
512        #[test]
513        fn test_256() {
514            assert_eq!(
515                TrigQuantizationMode::TwoFiveSixSteps,
516                TrigQuantizationMode::try_from(16_u8).unwrap()
517            );
518        }
519    }
520}
521
522#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, Eq, Hash, IntoUnsigneds)]
524pub enum TrigCondition {
525    None = 0,
528    Fill,
530    NotFill,
532    Pre,
534    NotPre,
536    Nei,
541    NotNei,
543    First,
545    NotFirst,
547    Percent1,
549    Percent2,
551    Percent4,
553    Percent6,
555    Percent9,
557    Percent13,
559    Percent19,
561    Percent25,
563    Percent33,
565    Percent41,
567    Percent50,
569    Percent59,
571    Percent67,
573    Percent75,
575    Percent81,
577    Percent87,
579    Percent91,
581    Percent94,
583    Percent96,
585    Percent98,
587    Percent99,
589    PatternT1R2,
591    PatternT2R2,
593    PatternT1R3,
595    PatternT2R3,
597    PatternT3R3,
599    PatternT1R4,
601    PatternT2R4,
603    PatternT3R4,
605    PatternT4R4,
607    PatternT1R5,
609    PatternT2R5,
611    PatternT3R5,
613    PatternT4R5,
615    PatternT5R5,
617    PatternT1R6,
619    PatternT2R6,
621    PatternT3R6,
623    PatternT4R6,
625    PatternT5R6,
627    PatternT6R6,
629    PatternT1R7,
631    PatternT2R7,
633    PatternT3R7,
635    PatternT4R7,
637    PatternT5R7,
639    PatternT6R7,
641    PatternT7R7,
643    PatternT1R8,
645    PatternT2R8,
647    PatternT3R8,
649    PatternT4R8,
651    PatternT5R8,
653    PatternT6R8,
655    PatternT7R8,
657    PatternT8R8,
659}
660
661#[enum_try_from_u32_to_unsigned_types]
662impl TryFrom<u32> for TrigCondition {
663    type Error = InvalidValueError;
664    fn try_from(value: u32) -> Result<Self, Self::Error> {
665        match value.rem_euclid(128) {
668            0 => Ok(TrigCondition::None),
669            1 => Ok(TrigCondition::Fill),
670            2 => Ok(TrigCondition::NotFill),
671            3 => Ok(TrigCondition::Pre),
672            4 => Ok(TrigCondition::NotPre),
673            5 => Ok(TrigCondition::Nei),
674            6 => Ok(TrigCondition::NotNei),
675            7 => Ok(TrigCondition::First),
676            8 => Ok(TrigCondition::NotFirst),
677            9 => Ok(TrigCondition::Percent1),
679            10 => Ok(TrigCondition::Percent2),
680            11 => Ok(TrigCondition::Percent4),
681            12 => Ok(TrigCondition::Percent6),
682            13 => Ok(TrigCondition::Percent9),
683            14 => Ok(TrigCondition::Percent13),
684            15 => Ok(TrigCondition::Percent19),
685            16 => Ok(TrigCondition::Percent25),
686            17 => Ok(TrigCondition::Percent33),
687            18 => Ok(TrigCondition::Percent41),
688            19 => Ok(TrigCondition::Percent50),
689            20 => Ok(TrigCondition::Percent59),
690            21 => Ok(TrigCondition::Percent67),
691            22 => Ok(TrigCondition::Percent75),
692            23 => Ok(TrigCondition::Percent81),
693            24 => Ok(TrigCondition::Percent87),
694            25 => Ok(TrigCondition::Percent91),
695            26 => Ok(TrigCondition::Percent94),
696            27 => Ok(TrigCondition::Percent96),
697            28 => Ok(TrigCondition::Percent98),
698            29 => Ok(TrigCondition::Percent99),
699            30 => Ok(TrigCondition::PatternT1R2),
701            31 => Ok(TrigCondition::PatternT2R2),
702            32 => Ok(TrigCondition::PatternT1R3),
704            33 => Ok(TrigCondition::PatternT2R3),
705            34 => Ok(TrigCondition::PatternT3R3),
706            35 => Ok(TrigCondition::PatternT1R4),
708            36 => Ok(TrigCondition::PatternT2R4),
709            37 => Ok(TrigCondition::PatternT3R4),
710            38 => Ok(TrigCondition::PatternT4R4),
711            39 => Ok(TrigCondition::PatternT1R5),
713            40 => Ok(TrigCondition::PatternT2R5),
714            41 => Ok(TrigCondition::PatternT3R5),
715            42 => Ok(TrigCondition::PatternT4R5),
716            43 => Ok(TrigCondition::PatternT5R5),
717            44 => Ok(TrigCondition::PatternT1R6),
719            45 => Ok(TrigCondition::PatternT2R6),
720            46 => Ok(TrigCondition::PatternT3R6),
721            47 => Ok(TrigCondition::PatternT4R6),
722            48 => Ok(TrigCondition::PatternT5R6),
723            49 => Ok(TrigCondition::PatternT6R6),
724            50 => Ok(TrigCondition::PatternT1R7),
726            51 => Ok(TrigCondition::PatternT2R7),
727            52 => Ok(TrigCondition::PatternT3R7),
728            53 => Ok(TrigCondition::PatternT4R7),
729            54 => Ok(TrigCondition::PatternT5R7),
730            55 => Ok(TrigCondition::PatternT6R7),
731            56 => Ok(TrigCondition::PatternT7R7),
732            57 => Ok(TrigCondition::PatternT1R8),
734            58 => Ok(TrigCondition::PatternT2R8),
735            59 => Ok(TrigCondition::PatternT3R8),
736            60 => Ok(TrigCondition::PatternT4R8),
737            61 => Ok(TrigCondition::PatternT5R8),
738            62 => Ok(TrigCondition::PatternT6R8),
739            63 => Ok(TrigCondition::PatternT7R8),
740            64 => Ok(TrigCondition::PatternT8R8),
741            _ => Err(InvalidValueError::TrigCondition),
743        }
744    }
745}
746
747#[cfg(test)]
748mod test_spec_trig_condition {
749
750    mod from_value {
751        use crate::settings::TrigCondition;
752
753        #[test]
754        fn none() {
755            assert_eq!(TrigCondition::None, TrigCondition::try_from(&0_u8).unwrap())
756        }
757        #[test]
758        fn fill() {
759            assert_eq!(TrigCondition::Fill, TrigCondition::try_from(&1_u8).unwrap())
760        }
761        #[test]
762        fn notfill() {
763            assert_eq!(
764                TrigCondition::NotFill,
765                TrigCondition::try_from(&2_u8).unwrap()
766            )
767        }
768        #[test]
769        fn pre() {
770            assert_eq!(TrigCondition::Pre, TrigCondition::try_from(&3_u8).unwrap())
771        }
772        #[test]
773        fn notpre() {
774            assert_eq!(
775                TrigCondition::NotPre,
776                TrigCondition::try_from(&4_u8).unwrap()
777            )
778        }
779        #[test]
780        fn nei() {
781            assert_eq!(TrigCondition::Nei, TrigCondition::try_from(&5_u8).unwrap())
782        }
783        #[test]
784        fn notnei() {
785            assert_eq!(
786                TrigCondition::NotNei,
787                TrigCondition::try_from(&6_u8).unwrap()
788            )
789        }
790        #[test]
791        fn first() {
792            assert_eq!(
793                TrigCondition::First,
794                TrigCondition::try_from(&7_u8).unwrap()
795            )
796        }
797        #[test]
798        fn notfirst() {
799            assert_eq!(
800                TrigCondition::NotFirst,
801                TrigCondition::try_from(&8_u8).unwrap()
802            )
803        }
804        #[test]
805        fn perc1() {
806            assert_eq!(
807                TrigCondition::Percent1,
808                TrigCondition::try_from(&9_u8).unwrap()
809            )
810        }
811        #[test]
812        fn perc2() {
813            assert_eq!(
814                TrigCondition::Percent2,
815                TrigCondition::try_from(&10_u8).unwrap()
816            )
817        }
818        #[test]
819        fn perc4() {
820            assert_eq!(
821                TrigCondition::Percent4,
822                TrigCondition::try_from(&11_u8).unwrap()
823            )
824        }
825        #[test]
826        fn perc6() {
827            assert_eq!(
828                TrigCondition::Percent6,
829                TrigCondition::try_from(&12_u8).unwrap()
830            )
831        }
832        #[test]
833        fn perc9() {
834            assert_eq!(
835                TrigCondition::Percent9,
836                TrigCondition::try_from(&13_u8).unwrap()
837            )
838        }
839        #[test]
840        fn perc13() {
841            assert_eq!(
842                TrigCondition::Percent13,
843                TrigCondition::try_from(&14_u8).unwrap()
844            )
845        }
846        #[test]
847        fn perc19() {
848            assert_eq!(
849                TrigCondition::Percent19,
850                TrigCondition::try_from(&15_u8).unwrap()
851            )
852        }
853        #[test]
854        fn perc25() {
855            assert_eq!(
856                TrigCondition::Percent25,
857                TrigCondition::try_from(&16_u8).unwrap()
858            )
859        }
860        #[test]
861        fn perc33() {
862            assert_eq!(
863                TrigCondition::Percent33,
864                TrigCondition::try_from(&17_u8).unwrap()
865            )
866        }
867        #[test]
868        fn perc41() {
869            assert_eq!(
870                TrigCondition::Percent41,
871                TrigCondition::try_from(&18_u8).unwrap()
872            )
873        }
874        #[test]
875        fn perc50() {
876            assert_eq!(
877                TrigCondition::Percent50,
878                TrigCondition::try_from(&19_u8).unwrap()
879            )
880        }
881        #[test]
882        fn perc59() {
883            assert_eq!(
884                TrigCondition::Percent59,
885                TrigCondition::try_from(&20_u8).unwrap()
886            )
887        }
888        #[test]
889        fn perc67() {
890            assert_eq!(
891                TrigCondition::Percent67,
892                TrigCondition::try_from(&21_u8).unwrap()
893            )
894        }
895        #[test]
896        fn perc75() {
897            assert_eq!(
898                TrigCondition::Percent75,
899                TrigCondition::try_from(&22_u8).unwrap()
900            )
901        }
902        #[test]
903        fn perc81() {
904            assert_eq!(
905                TrigCondition::Percent81,
906                TrigCondition::try_from(&23_u8).unwrap()
907            )
908        }
909        #[test]
910        fn perc87() {
911            assert_eq!(
912                TrigCondition::Percent87,
913                TrigCondition::try_from(&24_u8).unwrap()
914            )
915        }
916        #[test]
917        fn perc91() {
918            assert_eq!(
919                TrigCondition::Percent91,
920                TrigCondition::try_from(&25_u8).unwrap()
921            )
922        }
923        #[test]
924        fn perc94() {
925            assert_eq!(
926                TrigCondition::Percent94,
927                TrigCondition::try_from(&26_u8).unwrap()
928            )
929        }
930        #[test]
931        fn perc96() {
932            assert_eq!(
933                TrigCondition::Percent96,
934                TrigCondition::try_from(&27_u8).unwrap()
935            )
936        }
937        #[test]
938        fn perc98() {
939            assert_eq!(
940                TrigCondition::Percent98,
941                TrigCondition::try_from(&28_u8).unwrap()
942            )
943        }
944        #[test]
945        fn perc99() {
946            assert_eq!(
947                TrigCondition::Percent99,
948                TrigCondition::try_from(&29_u8).unwrap()
949            )
950        }
951        #[test]
952        fn pat_t1r2() {
953            assert_eq!(
954                TrigCondition::PatternT1R2,
955                TrigCondition::try_from(&30_u8).unwrap()
956            )
957        }
958        #[test]
959        fn pat_t2r2() {
960            assert_eq!(
961                TrigCondition::PatternT2R2,
962                TrigCondition::try_from(&31_u8).unwrap()
963            )
964        }
965        #[test]
966        fn pat_t1r3() {
967            assert_eq!(
968                TrigCondition::PatternT1R3,
969                TrigCondition::try_from(&32_u8).unwrap()
970            )
971        }
972        #[test]
973        fn pat_t2r3() {
974            assert_eq!(
975                TrigCondition::PatternT2R3,
976                TrigCondition::try_from(&33_u8).unwrap()
977            )
978        }
979        #[test]
980        fn pat_t3r3() {
981            assert_eq!(
982                TrigCondition::PatternT3R3,
983                TrigCondition::try_from(&34_u8).unwrap()
984            )
985        }
986
987        #[test]
988        fn pat_t1r4() {
989            assert_eq!(
990                TrigCondition::PatternT1R4,
991                TrigCondition::try_from(&35_u8).unwrap()
992            )
993        }
994        #[test]
995        fn pat_t2r4() {
996            assert_eq!(
997                TrigCondition::PatternT2R4,
998                TrigCondition::try_from(&36_u8).unwrap()
999            )
1000        }
1001        #[test]
1002        fn pat_t3r4() {
1003            assert_eq!(
1004                TrigCondition::PatternT3R4,
1005                TrigCondition::try_from(&37_u8).unwrap()
1006            )
1007        }
1008        #[test]
1009        fn pat_t4r4() {
1010            assert_eq!(
1011                TrigCondition::PatternT4R4,
1012                TrigCondition::try_from(&38_u8).unwrap()
1013            )
1014        }
1015
1016        #[test]
1017        fn pat_t1r5() {
1018            assert_eq!(
1019                TrigCondition::PatternT1R5,
1020                TrigCondition::try_from(&39_u8).unwrap()
1021            )
1022        }
1023        #[test]
1024        fn pat_t2r5() {
1025            assert_eq!(
1026                TrigCondition::PatternT2R5,
1027                TrigCondition::try_from(&40_u8).unwrap()
1028            )
1029        }
1030        #[test]
1031        fn pat_t3r5() {
1032            assert_eq!(
1033                TrigCondition::PatternT3R5,
1034                TrigCondition::try_from(&41_u8).unwrap()
1035            )
1036        }
1037        #[test]
1038        fn pat_t4r5() {
1039            assert_eq!(
1040                TrigCondition::PatternT4R5,
1041                TrigCondition::try_from(&42_u8).unwrap()
1042            )
1043        }
1044        #[test]
1045        fn pat_t5r5() {
1046            assert_eq!(
1047                TrigCondition::PatternT5R5,
1048                TrigCondition::try_from(&43_u8).unwrap()
1049            )
1050        }
1051
1052        #[test]
1053        fn pat_t1r6() {
1054            assert_eq!(
1055                TrigCondition::PatternT1R6,
1056                TrigCondition::try_from(&44_u8).unwrap()
1057            )
1058        }
1059        #[test]
1060        fn pat_t2r6() {
1061            assert_eq!(
1062                TrigCondition::PatternT2R6,
1063                TrigCondition::try_from(&45_u8).unwrap()
1064            )
1065        }
1066        #[test]
1067        fn pat_t3r6() {
1068            assert_eq!(
1069                TrigCondition::PatternT3R6,
1070                TrigCondition::try_from(&46_u8).unwrap()
1071            )
1072        }
1073        #[test]
1074        fn pat_t4r6() {
1075            assert_eq!(
1076                TrigCondition::PatternT4R6,
1077                TrigCondition::try_from(&47_u8).unwrap()
1078            )
1079        }
1080        #[test]
1081        fn pat_t5r6() {
1082            assert_eq!(
1083                TrigCondition::PatternT5R6,
1084                TrigCondition::try_from(&48_u8).unwrap()
1085            )
1086        }
1087        #[test]
1088        fn pat_t6r6() {
1089            assert_eq!(
1090                TrigCondition::PatternT6R6,
1091                TrigCondition::try_from(&49_u8).unwrap()
1092            )
1093        }
1094
1095        #[test]
1096        fn pat_t1r7() {
1097            assert_eq!(
1098                TrigCondition::PatternT1R7,
1099                TrigCondition::try_from(&50_u8).unwrap()
1100            )
1101        }
1102        #[test]
1103        fn pat_t2r7() {
1104            assert_eq!(
1105                TrigCondition::PatternT2R7,
1106                TrigCondition::try_from(&51_u8).unwrap()
1107            )
1108        }
1109        #[test]
1110        fn pat_t3r7() {
1111            assert_eq!(
1112                TrigCondition::PatternT3R7,
1113                TrigCondition::try_from(&52_u8).unwrap()
1114            )
1115        }
1116        #[test]
1117        fn pat_t4r7() {
1118            assert_eq!(
1119                TrigCondition::PatternT4R7,
1120                TrigCondition::try_from(&53_u8).unwrap()
1121            )
1122        }
1123        #[test]
1124        fn pat_t5r7() {
1125            assert_eq!(
1126                TrigCondition::PatternT5R7,
1127                TrigCondition::try_from(&54_u8).unwrap()
1128            )
1129        }
1130        #[test]
1131        fn pat_t6r7() {
1132            assert_eq!(
1133                TrigCondition::PatternT6R7,
1134                TrigCondition::try_from(&55_u8).unwrap()
1135            )
1136        }
1137        #[test]
1138        fn pat_t7r7() {
1139            assert_eq!(
1140                TrigCondition::PatternT7R7,
1141                TrigCondition::try_from(&56_u8).unwrap()
1142            )
1143        }
1144
1145        #[test]
1146        fn pat_t1r8() {
1147            assert_eq!(
1148                TrigCondition::PatternT1R8,
1149                TrigCondition::try_from(&57_u8).unwrap()
1150            )
1151        }
1152        #[test]
1153        fn pat_t2r8() {
1154            assert_eq!(
1155                TrigCondition::PatternT2R8,
1156                TrigCondition::try_from(&58_u8).unwrap()
1157            )
1158        }
1159        #[test]
1160        fn pat_t3r8() {
1161            assert_eq!(
1162                TrigCondition::PatternT3R8,
1163                TrigCondition::try_from(&59_u8).unwrap()
1164            )
1165        }
1166        #[test]
1167        fn pat_t4r8() {
1168            assert_eq!(
1169                TrigCondition::PatternT4R8,
1170                TrigCondition::try_from(&60_u8).unwrap()
1171            )
1172        }
1173        #[test]
1174        fn pat_t5r8() {
1175            assert_eq!(
1176                TrigCondition::PatternT5R8,
1177                TrigCondition::try_from(&61_u8).unwrap()
1178            )
1179        }
1180        #[test]
1181        fn pat_t6r8() {
1182            assert_eq!(
1183                TrigCondition::PatternT6R8,
1184                TrigCondition::try_from(&62_u8).unwrap()
1185            )
1186        }
1187        #[test]
1188        fn pat_t7r8() {
1189            assert_eq!(
1190                TrigCondition::PatternT7R8,
1191                TrigCondition::try_from(&63_u8).unwrap()
1192            )
1193        }
1194        #[test]
1195        fn pat_t8r8() {
1196            assert_eq!(
1197                TrigCondition::PatternT8R8,
1198                TrigCondition::try_from(&64_u8).unwrap()
1199            )
1200        }
1201    }
1202    mod get_value {
1203        use crate::settings::TrigCondition;
1204
1205        #[test]
1206        fn none() {
1207            assert_eq!(TrigCondition::None as u8, 0)
1208        }
1209        #[test]
1210        fn fill() {
1211            assert_eq!(TrigCondition::Fill as u8, 1)
1212        }
1213        #[test]
1214        fn notfill() {
1215            assert_eq!(TrigCondition::NotFill as u8, 2)
1216        }
1217        #[test]
1218        fn pre() {
1219            assert_eq!(TrigCondition::Pre as u8, 3)
1220        }
1221        #[test]
1222        fn notpre() {
1223            assert_eq!(TrigCondition::NotPre as u8, 4)
1224        }
1225        #[test]
1226        fn nei() {
1227            assert_eq!(TrigCondition::Nei as u8, 5)
1228        }
1229        #[test]
1230        fn notnei() {
1231            assert_eq!(TrigCondition::NotNei as u8, 6)
1232        }
1233        #[test]
1234        fn first() {
1235            assert_eq!(TrigCondition::First as u8, 7)
1236        }
1237        #[test]
1238        fn notfirst() {
1239            assert_eq!(TrigCondition::NotFirst as u8, 8)
1240        }
1241        #[test]
1242        fn perc1() {
1243            assert_eq!(TrigCondition::Percent1 as u8, 9)
1244        }
1245        #[test]
1246        fn perc2() {
1247            assert_eq!(TrigCondition::Percent2 as u8, 10)
1248        }
1249        #[test]
1250        fn perc4() {
1251            assert_eq!(TrigCondition::Percent4 as u8, 11)
1252        }
1253        #[test]
1254        fn perc6() {
1255            assert_eq!(TrigCondition::Percent6 as u8, 12)
1256        }
1257        #[test]
1258        fn perc9() {
1259            assert_eq!(TrigCondition::Percent9 as u8, 13)
1260        }
1261        #[test]
1262        fn perc13() {
1263            assert_eq!(TrigCondition::Percent13 as u8, 14)
1264        }
1265        #[test]
1266        fn perc19() {
1267            assert_eq!(TrigCondition::Percent19 as u8, 15)
1268        }
1269        #[test]
1270        fn perc25() {
1271            assert_eq!(TrigCondition::Percent25 as u8, 16)
1272        }
1273        #[test]
1274        fn perc33() {
1275            assert_eq!(TrigCondition::Percent33 as u8, 17)
1276        }
1277        #[test]
1278        fn perc41() {
1279            assert_eq!(TrigCondition::Percent41 as u8, 18)
1280        }
1281        #[test]
1282        fn perc50() {
1283            assert_eq!(TrigCondition::Percent50 as u8, 19)
1284        }
1285        #[test]
1286        fn perc59() {
1287            assert_eq!(TrigCondition::Percent59 as u8, 20)
1288        }
1289        #[test]
1290        fn perc67() {
1291            assert_eq!(TrigCondition::Percent67 as u8, 21)
1292        }
1293        #[test]
1294        fn perc75() {
1295            assert_eq!(TrigCondition::Percent75 as u8, 22)
1296        }
1297        #[test]
1298        fn perc81() {
1299            assert_eq!(TrigCondition::Percent81 as u8, 23)
1300        }
1301        #[test]
1302        fn perc87() {
1303            assert_eq!(TrigCondition::Percent87 as u8, 24)
1304        }
1305        #[test]
1306        fn perc91() {
1307            assert_eq!(TrigCondition::Percent91 as u8, 25)
1308        }
1309        #[test]
1310        fn perc94() {
1311            assert_eq!(TrigCondition::Percent94 as u8, 26)
1312        }
1313        #[test]
1314        fn perc96() {
1315            assert_eq!(TrigCondition::Percent96 as u8, 27)
1316        }
1317        #[test]
1318        fn perc98() {
1319            assert_eq!(TrigCondition::Percent98 as u8, 28)
1320        }
1321        #[test]
1322        fn perc99() {
1323            assert_eq!(TrigCondition::Percent99 as u8, 29)
1324        }
1325        #[test]
1326        fn pat_t1r2() {
1327            assert_eq!(TrigCondition::PatternT1R2 as u8, 30)
1328        }
1329        #[test]
1330        fn pat_t2r2() {
1331            assert_eq!(TrigCondition::PatternT2R2 as u8, 31)
1332        }
1333        #[test]
1334        fn pat_t1r3() {
1335            assert_eq!(TrigCondition::PatternT1R3 as u8, 32)
1336        }
1337        #[test]
1338        fn pat_t2r3() {
1339            assert_eq!(TrigCondition::PatternT2R3 as u8, 33)
1340        }
1341        #[test]
1342        fn pat_t3r3() {
1343            assert_eq!(TrigCondition::PatternT3R3 as u8, 34)
1344        }
1345
1346        #[test]
1347        fn pat_t1r4() {
1348            assert_eq!(TrigCondition::PatternT1R4 as u8, 35)
1349        }
1350        #[test]
1351        fn pat_t2r4() {
1352            assert_eq!(TrigCondition::PatternT2R4 as u8, 36)
1353        }
1354        #[test]
1355        fn pat_t3r4() {
1356            assert_eq!(TrigCondition::PatternT3R4 as u8, 37)
1357        }
1358        #[test]
1359        fn pat_t4r4() {
1360            assert_eq!(TrigCondition::PatternT4R4 as u8, 38)
1361        }
1362
1363        #[test]
1364        fn pat_t1r5() {
1365            assert_eq!(TrigCondition::PatternT1R5 as u8, 39)
1366        }
1367        #[test]
1368        fn pat_t2r5() {
1369            assert_eq!(TrigCondition::PatternT2R5 as u8, 40)
1370        }
1371        #[test]
1372        fn pat_t3r5() {
1373            assert_eq!(TrigCondition::PatternT3R5 as u8, 41)
1374        }
1375        #[test]
1376        fn pat_t4r5() {
1377            assert_eq!(TrigCondition::PatternT4R5 as u8, 42)
1378        }
1379        #[test]
1380        fn pat_t5r5() {
1381            assert_eq!(TrigCondition::PatternT5R5 as u8, 43)
1382        }
1383
1384        #[test]
1385        fn pat_t1r6() {
1386            assert_eq!(TrigCondition::PatternT1R6 as u8, 44)
1387        }
1388        #[test]
1389        fn pat_t2r6() {
1390            assert_eq!(TrigCondition::PatternT2R6 as u8, 45)
1391        }
1392        #[test]
1393        fn pat_t3r6() {
1394            assert_eq!(TrigCondition::PatternT3R6 as u8, 46)
1395        }
1396        #[test]
1397        fn pat_t4r6() {
1398            assert_eq!(TrigCondition::PatternT4R6 as u8, 47)
1399        }
1400        #[test]
1401        fn pat_t5r6() {
1402            assert_eq!(TrigCondition::PatternT5R6 as u8, 48)
1403        }
1404        #[test]
1405        fn pat_t6r6() {
1406            assert_eq!(TrigCondition::PatternT6R6 as u8, 49)
1407        }
1408
1409        #[test]
1410        fn pat_t1r7() {
1411            assert_eq!(TrigCondition::PatternT1R7 as u8, 50)
1412        }
1413        #[test]
1414        fn pat_t2r7() {
1415            assert_eq!(TrigCondition::PatternT2R7 as u8, 51)
1416        }
1417        #[test]
1418        fn pat_t3r7() {
1419            assert_eq!(TrigCondition::PatternT3R7 as u8, 52)
1420        }
1421        #[test]
1422        fn pat_t4r7() {
1423            assert_eq!(TrigCondition::PatternT4R7 as u8, 53)
1424        }
1425        #[test]
1426        fn pat_t5r7() {
1427            assert_eq!(TrigCondition::PatternT5R7 as u8, 54)
1428        }
1429        #[test]
1430        fn pat_t6r7() {
1431            assert_eq!(TrigCondition::PatternT6R7 as u8, 55)
1432        }
1433        #[test]
1434        fn pat_t7r7() {
1435            assert_eq!(TrigCondition::PatternT7R7 as u8, 56)
1436        }
1437
1438        #[test]
1439        fn pat_t1r8() {
1440            assert_eq!(TrigCondition::PatternT1R8 as u8, 57)
1441        }
1442        #[test]
1443        fn pat_t2r8() {
1444            assert_eq!(TrigCondition::PatternT2R8 as u8, 58)
1445        }
1446        #[test]
1447        fn pat_t3r8() {
1448            assert_eq!(TrigCondition::PatternT3R8 as u8, 59)
1449        }
1450        #[test]
1451        fn pat_t4r8() {
1452            assert_eq!(TrigCondition::PatternT4R8 as u8, 60)
1453        }
1454        #[test]
1455        fn pat_t5r8() {
1456            assert_eq!(TrigCondition::PatternT5R8 as u8, 61)
1457        }
1458        #[test]
1459        fn pat_t6r8() {
1460            assert_eq!(TrigCondition::PatternT6R8 as u8, 62)
1461        }
1462        #[test]
1463        fn pat_t7r8() {
1464            assert_eq!(TrigCondition::PatternT7R8 as u8, 63)
1465        }
1466        #[test]
1467        fn pat_t8r8() {
1468            assert_eq!(TrigCondition::PatternT8R8 as u8, 64)
1469        }
1470    }
1471}
1472
1473#[derive(PartialEq, Debug, Clone, Default, Serialize, Deserialize, Copy, IntoSigneds)]
1476#[repr(i8)]
1477pub enum MidiChannel {
1478    #[default]
1480    Disabled = -1,
1481    One = 1,
1484    Two = 2,
1486    Three = 3,
1488    Four = 4,
1490    Five = 5,
1492    Six = 6,
1494    Seven = 7,
1496    Eight = 8,
1498    Nine = 9,
1500    Ten = 10,
1502    Eleven = 11,
1504    Twelve = 12,
1506    Thirteen = 13,
1508    Fourteen = 14,
1510    Fifteen = 15,
1512    Sixteen = 16,
1514}
1515
1516#[enum_try_from_i32_to_signed_types]
1517impl TryFrom<i32> for MidiChannel {
1518    type Error = InvalidValueError;
1519    fn try_from(value: i32) -> Result<Self, Self::Error> {
1520        match value {
1521            -1 => Ok(Self::Disabled),
1522            1 => Ok(Self::One),
1523            2 => Ok(Self::Two),
1524            3 => Ok(Self::Three),
1525            4 => Ok(Self::Four),
1526            5 => Ok(Self::Five),
1527            6 => Ok(Self::Six),
1528            7 => Ok(Self::Seven),
1529            8 => Ok(Self::Eight),
1530            9 => Ok(Self::Nine),
1531            10 => Ok(Self::Ten),
1532            11 => Ok(Self::Eleven),
1533            12 => Ok(Self::Twelve),
1534            13 => Ok(Self::Thirteen),
1535            14 => Ok(Self::Fourteen),
1536            15 => Ok(Self::Fifteen),
1537            16 => Ok(Self::Sixteen),
1538            _ => Err(InvalidValueError::MidiChannel),
1539        }
1540    }
1541}
1542
1543#[cfg(test)]
1544#[allow(unused_imports)]
1545mod test_spec {
1546
1547    mod value {
1548        use crate::settings::MidiChannel;
1549
1550        #[test]
1551        fn test_disabled() {
1552            assert_eq!(MidiChannel::Disabled as i8, -1);
1553        }
1554        #[test]
1555        fn test_1() {
1556            assert_eq!(MidiChannel::One as i8, 1);
1557        }
1558        #[test]
1559        fn test_2() {
1560            assert_eq!(MidiChannel::Two as i8, 2);
1561        }
1562        #[test]
1563        fn test_3() {
1564            assert_eq!(MidiChannel::Three as i8, 3);
1565        }
1566        #[test]
1567        fn test_4() {
1568            assert_eq!(MidiChannel::Four as i8, 4);
1569        }
1570        #[test]
1571        fn test_5() {
1572            assert_eq!(MidiChannel::Five as i8, 5);
1573        }
1574        #[test]
1575        fn test_6() {
1576            assert_eq!(MidiChannel::Six as i8, 6);
1577        }
1578        #[test]
1579        fn test_7() {
1580            assert_eq!(MidiChannel::Seven as i8, 7);
1581        }
1582        #[test]
1583        fn test_8() {
1584            assert_eq!(MidiChannel::Eight as i8, 8);
1585        }
1586        #[test]
1587        fn test_9() {
1588            assert_eq!(MidiChannel::Nine as i8, 9);
1589        }
1590        #[test]
1591        fn test_10() {
1592            assert_eq!(MidiChannel::Ten as i8, 10);
1593        }
1594        #[test]
1595        fn test_11() {
1596            assert_eq!(MidiChannel::Eleven as i8, 11);
1597        }
1598        #[test]
1599        fn test_12() {
1600            assert_eq!(MidiChannel::Twelve as i8, 12);
1601        }
1602        #[test]
1603        fn test_13() {
1604            assert_eq!(MidiChannel::Thirteen as i8, 13);
1605        }
1606        #[test]
1607        fn test_14() {
1608            assert_eq!(MidiChannel::Fourteen as i8, 14);
1609        }
1610        #[test]
1611        fn test_15() {
1612            assert_eq!(MidiChannel::Fifteen as i8, 15);
1613        }
1614        #[test]
1615        fn test_16() {
1616            assert_eq!(MidiChannel::Sixteen as i8, 16);
1617        }
1618    }
1619
1620    mod from_value {
1621
1622        use crate::settings::MidiChannel;
1623
1624        #[test]
1625        fn test_error_1() {
1626            assert!(MidiChannel::try_from(&100_i8).is_err());
1627        }
1628        #[test]
1629        fn test_error_2() {
1630            assert!(MidiChannel::try_from(&0_i8).is_err());
1631        }
1632        #[test]
1633        fn test_disabled() {
1634            assert_eq!(
1635                MidiChannel::Disabled,
1636                MidiChannel::try_from(&-1_i8).unwrap()
1637            );
1638        }
1639        #[test]
1640        fn test_1() {
1641            assert_eq!(MidiChannel::One, MidiChannel::try_from(&1_i8).unwrap());
1642        }
1643        #[test]
1644        fn test_2() {
1645            assert_eq!(MidiChannel::Two, MidiChannel::try_from(&2_i8).unwrap());
1646        }
1647        #[test]
1648        fn test_3() {
1649            assert_eq!(MidiChannel::Three, MidiChannel::try_from(&3_i8).unwrap());
1650        }
1651        #[test]
1652        fn test_4() {
1653            assert_eq!(MidiChannel::Four, MidiChannel::try_from(&4_i8).unwrap());
1654        }
1655        #[test]
1656        fn test_5() {
1657            assert_eq!(MidiChannel::Five, MidiChannel::try_from(&5_i8).unwrap());
1658        }
1659        #[test]
1660        fn test_6() {
1661            assert_eq!(MidiChannel::Six, MidiChannel::try_from(&6_i8).unwrap());
1662        }
1663        #[test]
1664        fn test_7() {
1665            assert_eq!(MidiChannel::Seven, MidiChannel::try_from(&7_i8).unwrap());
1666        }
1667        #[test]
1668        fn test_8() {
1669            assert_eq!(MidiChannel::Eight, MidiChannel::try_from(&8_i8).unwrap());
1670        }
1671        #[test]
1672        fn test_9() {
1673            assert_eq!(MidiChannel::Nine, MidiChannel::try_from(&9_i8).unwrap());
1674        }
1675        #[test]
1676        fn test_10() {
1677            assert_eq!(MidiChannel::Ten, MidiChannel::try_from(&10_i8).unwrap());
1678        }
1679        #[test]
1680        fn test_11() {
1681            assert_eq!(MidiChannel::Eleven, MidiChannel::try_from(&11_i8).unwrap());
1682        }
1683        #[test]
1684        fn test_12() {
1685            assert_eq!(MidiChannel::Twelve, MidiChannel::try_from(&12_i8).unwrap());
1686        }
1687        #[test]
1688        fn test_13() {
1689            assert_eq!(
1690                MidiChannel::Thirteen,
1691                MidiChannel::try_from(&13_i8).unwrap()
1692            );
1693        }
1694        #[test]
1695        fn test_14() {
1696            assert_eq!(
1697                MidiChannel::Fourteen,
1698                MidiChannel::try_from(&14_i8).unwrap()
1699            );
1700        }
1701        #[test]
1702        fn test_15() {
1703            assert_eq!(MidiChannel::Fifteen, MidiChannel::try_from(&15_i8).unwrap());
1704        }
1705        #[test]
1706        fn test_16() {
1707            assert_eq!(MidiChannel::Sixteen, MidiChannel::try_from(&16_i8).unwrap());
1708        }
1709    }
1710}
1711
1712#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, Eq, Hash)]
1714pub enum SlotType {
1715    Static,
1717    Flex,
1719}
1720
1721impl SlotType {
1722    pub fn other(&self) -> Self {
1723        match self {
1724            Self::Static => Self::Flex,
1725            Self::Flex => Self::Static,
1726        }
1727    }
1728}
1729
1730impl TryFrom<String> for SlotType {
1731    type Error = InvalidValueError;
1732    fn try_from(value: String) -> Result<Self, Self::Error> {
1733        match value.to_ascii_uppercase().as_str() {
1734            "STATIC" => Ok(SlotType::Static),
1735            "FLEX" => Ok(SlotType::Flex),
1736            _ => Err(InvalidValueError::SlotType),
1737        }
1738    }
1739}
1740
1741impl TryFrom<&str> for SlotType {
1742    type Error = InvalidValueError;
1743    fn try_from(value: &str) -> Result<Self, Self::Error> {
1744        Self::try_from(value.to_string())
1745    }
1746}
1747
1748impl Display for SlotType {
1749    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1750        let str = match self {
1751            SlotType::Static => "STATIC".to_string(),
1752            SlotType::Flex => "FLEX".to_string(),
1753        };
1754        write!(f, "{str}")
1755    }
1756}
1757
1758impl From<SlotType> for String {
1759    fn from(value: SlotType) -> Self {
1760        value.to_string()
1761    }
1762}
1763
1764#[cfg(test)]
1765mod slot_type {
1766    mod value {
1767        use crate::settings::SlotType;
1768
1769        #[test]
1770        fn test_static() {
1771            assert_eq!(SlotType::Static.to_string(), "STATIC");
1772        }
1773        #[test]
1774        fn test_flex() {
1775            assert_eq!(SlotType::Flex.to_string(), "FLEX");
1776        }
1777    }
1778
1779    mod from_value {
1780        use crate::settings::SlotType;
1781
1782        #[test]
1783        fn test_error() {
1784            assert!(SlotType::try_from("SOME INCORRECT STRING").is_err());
1785        }
1786
1787        #[test]
1788        fn test_static_upper() {
1789            assert_eq!(SlotType::Static, SlotType::try_from("STATIC").unwrap(),);
1790        }
1791
1792        #[test]
1793        fn test_static_lower() {
1794            assert_eq!(SlotType::Static, SlotType::try_from("static").unwrap(),);
1795        }
1796
1797        #[test]
1798        fn test_flex_upper() {
1799            assert_eq!(SlotType::Flex, SlotType::try_from("FLEX").unwrap(),);
1800        }
1801
1802        #[test]
1803        fn test_flex_lower() {
1804            assert_eq!(SlotType::Flex, SlotType::try_from("flex").unwrap(),);
1805        }
1806    }
1807}