1use crate::triad::TriadBase;
7
8use crate::traits::{TriadRepr, TriadReprMut, TriadType};
9use crate::types::{Factors, LPR};
10use num_traits::{FromPrimitive, One, Zero};
11use rstmt_core::{PitchMod, Transform};
12
13impl<S, T, K> Transform<LPR> for TriadBase<S, K, T>
14where
15 K: TriadType,
16 K::Rel: TriadType,
17 S: TriadRepr<Elem = T>,
18 T: Copy
19 + FromPrimitive
20 + One
21 + PitchMod<Output = T>
22 + core::ops::Add<Output = T>
23 + core::ops::Sub<Output = T>,
24{
25 type Output = TriadBase<S, K::Rel, T>;
26
27 fn transform(self, transformation: LPR) -> Self::Output {
28 LPR::apply(transformation, self)
29 }
30}
31
32impl<T, S, K> core::fmt::Debug for TriadBase<S, K, T>
33where
34 S: TriadRepr<Elem = T> + core::fmt::Debug,
35 K: TriadType,
36 T: core::fmt::Debug,
37{
38 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
39 write!(f, "{:?}-{:?} ({:?})", self.root(), self.class, self.chord)
40 }
41}
42
43impl<T, S, K> core::fmt::Display for TriadBase<S, K, T>
44where
45 S: TriadRepr<Elem = T> + core::fmt::Debug,
46 K: TriadType + core::fmt::Display,
47 T: core::fmt::Display,
48{
49 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
50 write!(
51 f,
52 "{{ chord: {:?}, class: {}, octave: {} }}",
53 self.chord, self.class, self.octave
54 )
55 }
56}
57
58impl<T, S, K> AsRef<S> for TriadBase<S, K, T>
59where
60 S: TriadRepr<Elem = T>,
61 K: TriadType,
62{
63 fn as_ref(&self) -> &S {
64 self.chord()
65 }
66}
67
68impl<T, S, K> AsMut<S> for TriadBase<S, K, T>
69where
70 S: TriadRepr<Elem = T>,
71 K: TriadType,
72{
73 fn as_mut(&mut self) -> &mut S {
74 self.chord_mut()
75 }
76}
77
78impl<T, S, K> core::borrow::Borrow<S> for TriadBase<S, K, T>
79where
80 S: TriadRepr<Elem = T>,
81 K: TriadType,
82{
83 fn borrow(&self) -> &S {
84 self.chord()
85 }
86}
87
88impl<T, S, K> core::borrow::BorrowMut<S> for TriadBase<S, K, T>
89where
90 S: TriadRepr<Elem = T>,
91 K: TriadType,
92{
93 fn borrow_mut(&mut self) -> &mut S {
94 self.chord_mut()
95 }
96}
97
98impl<T, S, K> core::ops::Deref for TriadBase<S, K, T>
99where
100 S: TriadRepr<Elem = T>,
101 K: TriadType,
102{
103 type Target = S;
104
105 fn deref(&self) -> &Self::Target {
106 self.chord()
107 }
108}
109
110impl<T, S, K> core::ops::DerefMut for TriadBase<S, K, T>
111where
112 S: TriadRepr<Elem = T>,
113 K: TriadType,
114{
115 fn deref_mut(&mut self) -> &mut Self::Target {
116 self.chord_mut()
117 }
118}
119
120impl<T, S, K> core::ops::Index<Factors> for TriadBase<S, K, T>
121where
122 S: TriadRepr<Elem = T>,
123 K: TriadType,
124{
125 type Output = T;
126
127 fn index(&self, index: Factors) -> &Self::Output {
128 match index {
129 Factors::Root => self.chord().root(),
130 Factors::Third => self.chord().third(),
131 Factors::Fifth => self.chord().fifth(),
132 }
133 }
134}
135
136impl<T, S, K> core::ops::IndexMut<Factors> for TriadBase<S, K, T>
137where
138 S: TriadReprMut<Elem = T>,
139 K: TriadType,
140{
141 fn index_mut(&mut self, index: Factors) -> &mut Self::Output {
142 match index {
143 Factors::Root => self.chord_mut().root_mut(),
144 Factors::Third => self.chord_mut().third_mut(),
145 Factors::Fifth => self.chord_mut().fifth_mut(),
146 }
147 }
148}
149
150impl<S, T, K, I> IntoIterator for TriadBase<S, K, T>
151where
152 S: TriadRepr<Elem = T> + IntoIterator<Item = I::Item, IntoIter = I>,
153 K: TriadType,
154 I: core::iter::Iterator<Item = T>,
155{
156 type Item = T;
157 type IntoIter = I;
158
159 fn into_iter(self) -> Self::IntoIter {
160 self.chord.into_iter()
161 }
162}
163
164impl<'a, S, T, K, I> IntoIterator for &'a TriadBase<S, K, T>
165where
166 S: TriadRepr<Elem = T>,
167 K: TriadType,
168 I: core::iter::Iterator<Item = &'a T>,
169 &'a S: IntoIterator<Item = I::Item, IntoIter = I>,
170{
171 type Item = &'a T;
172 type IntoIter = I;
173
174 fn into_iter(self) -> Self::IntoIter {
175 self.chord().into_iter()
176 }
177}
178
179impl<'a, S, T, K, I> IntoIterator for &'a mut TriadBase<S, K, T>
180where
181 S: TriadRepr<Elem = T>,
182 K: TriadType,
183 I: core::iter::Iterator<Item = &'a T>,
184 &'a mut S: IntoIterator<Item = I::Item, IntoIter = I>,
185{
186 type Item = &'a T;
187 type IntoIter = I;
188
189 fn into_iter(self) -> Self::IntoIter {
190 self.chord_mut().into_iter()
191 }
192}
193
194impl<S, T, K> PartialEq<S> for TriadBase<S, K, T>
195where
196 S: TriadRepr<Elem = T> + PartialEq,
197 K: TriadType,
198{
199 fn eq(&self, other: &S) -> bool {
200 self.chord() == other
201 }
202}
203
204impl<S1, T1, K1, S2, T2, K2> PartialEq<TriadBase<S2, K2, T2>> for TriadBase<S1, K1, T1>
205where
206 S1: TriadRepr<Elem = T1> + PartialEq<S2>,
207 K1: TriadType,
208 S2: TriadRepr<Elem = T2>,
209 K2: TriadType,
210{
211 fn eq(&self, other: &TriadBase<S2, K2, T2>) -> bool {
212 self.chord() == other.chord()
213 }
214}
215
216impl<T, S, K> From<(S, K)> for TriadBase<S, K, T>
217where
218 S: TriadRepr<Elem = T>,
219 T: Zero,
220 K: TriadType,
221{
222 fn from((chord, class): (S, K)) -> Self {
223 Self::new(chord, class)
224 }
225}