sim_lib_pitch_serial/
operation.rs1use std::fmt::{Display, Formatter};
4
5#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub enum RowFamily {
8 P,
10 I,
12 R,
14 RI,
16}
17
18impl RowFamily {
19 pub const fn as_str(self) -> &'static str {
21 match self {
22 Self::P => "P",
23 Self::I => "I",
24 Self::R => "R",
25 Self::RI => "RI",
26 }
27 }
28
29 pub(crate) const fn is_inverted(self) -> bool {
30 matches!(self, Self::I | Self::RI)
31 }
32
33 pub(crate) const fn is_retrograde(self) -> bool {
34 matches!(self, Self::R | Self::RI)
35 }
36}
37
38impl Display for RowFamily {
39 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
40 formatter.write_str(self.as_str())
41 }
42}
43
44#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
51pub struct RowOperation {
52 pub family: RowFamily,
54 pub addend: u8,
56}
57
58impl RowOperation {
59 pub const fn new(family: RowFamily, addend: u8) -> Self {
61 Self {
62 family,
63 addend: addend % 12,
64 }
65 }
66
67 pub const fn normalized(self) -> Self {
69 Self::new(self.family, self.addend)
70 }
71
72 pub const fn inverse(self) -> Self {
74 let operation = self.normalized();
75 let addend = match operation.family {
76 RowFamily::P | RowFamily::R => (12 - operation.addend) % 12,
77 RowFamily::I | RowFamily::RI => operation.addend,
78 };
79 Self::new(operation.family, addend)
80 }
81}
82
83impl Display for RowOperation {
84 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
85 let operation = self.normalized();
86 write!(formatter, "{}{}", operation.family, operation.addend)
87 }
88}