rstmt_nrt/traits/
triad_type.rs1use crate::Triads;
7pub trait Relative {
10 type Rel;
11
12 private! {}
13
14 fn rel(&self) -> Self::Rel;
15}
16
17pub trait TriadType
20where
21 Self: 'static + Copy + Relative + Send + Sync + core::fmt::Debug + core::fmt::Display,
22{
23 private! {}
24
25 fn new() -> Self
26 where
27 Self: Sized;
28
29 fn root(&self) -> usize;
30
31 fn fifth(&self) -> usize;
32
33 fn third(&self) -> usize;
34 fn dynamic(&self) -> crate::Triads {
36 if self.is_major() {
37 Triads::Major
38 } else if self.is_minor() {
39 Triads::Minor
40 } else if self.is_augmented() {
41 Triads::Augmented
42 } else if self.is_diminished() {
43 Triads::Diminished
44 } else {
45 unreachable!("invalid triad type")
46 }
47 }
48
49 fn is_major(&self) -> bool {
50 false
51 }
52
53 fn is_minor(&self) -> bool {
54 false
55 }
56
57 fn is_augmented(&self) -> bool {
58 false
59 }
60
61 fn is_diminished(&self) -> bool {
62 false
63 }
64}
65
66pub trait RelTriad: TriadType + Relative
67where
68 Self::Rel: TriadType,
69{
70 private! {}
71
72 fn relative(&self) -> Self::Rel;
73}
74
75impl<A, B> RelTriad for A
80where
81 A: TriadType + Relative<Rel = B>,
82 B: TriadType,
83{
84 seal! {}
85
86 fn relative(&self) -> B {
87 <B>::new()
88 }
89}
90
91impl Relative for Triads {
92 type Rel = Triads;
93
94 seal! {}
95
96 fn rel(&self) -> Self::Rel {
97 self.relative()
98 }
99}
100
101impl TriadType for Triads {
102 seal! {}
103
104 fn new() -> Self {
105 Self::default()
106 }
107
108 fn is_major(&self) -> bool {
109 matches!(self, Triads::Major)
110 }
111
112 fn is_minor(&self) -> bool {
113 matches!(self, Triads::Minor)
114 }
115
116 fn is_augmented(&self) -> bool {
117 matches!(self, Triads::Augmented)
118 }
119
120 fn is_diminished(&self) -> bool {
121 matches!(self, Triads::Diminished)
122 }
123
124 fn root(&self) -> usize {
125 self.root()
126 }
127
128 fn fifth(&self) -> usize {
129 self.fifth()
130 }
131
132 fn third(&self) -> usize {
133 self.third()
134 }
135}
136
137macro_rules! triad_kind {
138 (impl $trait:ident for {$($($name:ident)::*<Rel = $rel:ty>::<[$($v:literal),* $(,)?]> $({$($rest:tt)*})?),* $(,)?}) => {
139 $(triad_kind! { @impl $trait for $($name)::*<Rel = $rel>::<[$($v),*]> $({$($rest)*})? })*
140 };
141 (@impl $trait:ident for $($name:ident)::* <Rel = $rel:ty>::<[$r:literal, $f:literal, $t:literal]> $({$($rest:tt)*})?) => {
142 impl $trait for $($name)::* {
143 seal! {}
146
147 fn new() -> Self {
148 Self::default()
149 }
150
151 fn root(&self) -> usize {
152 $r
153 }
154
155 fn fifth(&self) -> usize {
156 $f
157 }
158
159 fn third(&self) -> usize {
160 $t
161 }
162
163 $($($rest)*)?
164 }
165
166 impl Relative for $($name)::* {
167 type Rel = $rel;
168
169 seal! {}
170
171 fn rel(&self) -> Self::Rel {
172 <$rel>::default()
173 }
174 }
175 };
176}
177
178triad_kind! {
179 impl TriadType for {
180 rstmt_core::Augmented<Rel = rstmt_core::Diminished>::<[4, 8, 4]> {
181 fn is_augmented(&self) -> bool {
182 true
183 }
184 },
185 rstmt_core::Diminished<Rel = rstmt_core::Augmented>::<[3, 6, 3]> {
186 fn is_diminished(&self) -> bool {
187 true
188 }
189 },
190 rstmt_core::Major<Rel = rstmt_core::Minor>::<[4, 7, 3]> {
191 fn is_major(&self) -> bool {
192 true
193 }
194 },
195 rstmt_core::Minor<Rel = rstmt_core::Major>::<[3, 7, 4]> {
196 fn is_minor(&self) -> bool {
197 true
198 }
199 }
200 }
201}