eryon_nrt/triad/
factors.rs1use strum::IntoEnumIterator;
6
7#[derive(
11 Clone,
12 Copy,
13 Debug,
14 Eq,
15 Hash,
16 Ord,
17 PartialEq,
18 PartialOrd,
19 strum::AsRefStr,
20 strum::Display,
21 strum::EnumCount,
22 strum::EnumDiscriminants,
23 strum::EnumIs,
24 strum::VariantNames,
25)]
26#[cfg_attr(
27 feature = "serde",
28 derive(serde::Deserialize, serde::Serialize),
29 serde(rename_all = "lowercase"),
30 strum_discriminants(
31 derive(serde::Deserialize, serde::Serialize),
32 serde(rename_all = "lowercase")
33 )
34)]
35#[strum_discriminants(
36 name(Factors),
37 derive(
38 Hash,
39 Ord,
40 PartialOrd,
41 strum::AsRefStr,
42 strum::Display,
43 strum::EnumCount,
44 strum::EnumIter,
45 strum::EnumString,
46 strum::VariantNames
47 )
48)]
49#[repr(usize)]
50pub enum Components<T = usize> {
51 #[strum(serialize = "r", serialize = "root")]
52 Root(T) = 0,
53 #[strum(serialize = "t", serialize = "third")]
54 Third(T) = 1,
55 #[strum(serialize = "f", serialize = "fifth")]
56 Fifth(T) = 2,
57}
58
59impl<T> Components<T> {
60 pub fn new(data: T, factor: Factors) -> Self {
61 match factor {
62 Factors::Root => Self::Root(data),
63 Factors::Third => Self::Third(data),
64 Factors::Fifth => Self::Fifth(data),
65 }
66 }
67 pub fn factor(&self) -> Factors {
69 match self {
70 Self::Root(_) => Factors::Root,
71 Self::Third(_) => Factors::Third,
72 Self::Fifth(_) => Factors::Fifth,
73 }
74 }
75 pub fn fifth(data: T) -> Self {
77 Self::Fifth(data)
78 }
79 pub fn root(data: T) -> Self {
81 Self::Root(data)
82 }
83 pub fn third(data: T) -> Self {
85 Self::Third(data)
86 }
87}
88
89mod impl_factors {
90 use super::*;
91
92 impl Factors {
93 pub fn root() -> Self {
94 Self::Root
95 }
96
97 pub fn third() -> Self {
98 Self::Third
99 }
100
101 pub fn fifth() -> Self {
102 Self::Fifth
103 }
104
105 pub fn factors() -> [Self; 3] {
106 use Factors::*;
107 [Root, Third, Fifth]
108 }
109
110 pub fn others(&self) -> Vec<Self> {
111 Self::iter().filter(|x| x != self).collect()
112 }
113 }
114
115 impl Default for Factors {
116 fn default() -> Self {
117 Factors::Root
118 }
119 }
120
121 impl From<usize> for Factors {
122 fn from(x: usize) -> Self {
123 use strum::EnumCount;
124 match x % Self::COUNT {
125 0 => Factors::Root,
126 1 => Factors::Third,
127 _ => Factors::Fifth,
128 }
129 }
130 }
131
132 impl From<Factors> for usize {
133 fn from(x: Factors) -> Self {
134 x as usize
135 }
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142
143 #[test]
144 fn chord_factors() {
145
146 }
148
149 #[test]
150 fn chord_factors_iter() {
151 use Factors::*;
152
153 let factors = Factors::factors();
154 assert_eq!(factors.len(), 3);
155 assert_eq!(factors[0], Root);
156 assert_eq!(factors[1], Third);
157 assert_eq!(factors[2], Fifth);
158 }
159}