1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::collections::HashMap;
use wasm_bindgen::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct Triad {
pub notes: [String; 3],
pub kind: String,
}
pub fn get_triad(mut note: String) -> Triad {
let tones = [
"c", "cis", "d", "dis", "e", "f", "fis", "g", "gis", "a", "ais", "h",
];
let mut replacements = HashMap::new();
replacements.insert("des".to_string(), "cis".to_string());
replacements.insert("es".to_string(), "dis".to_string());
replacements.insert("ges".to_string(), "fis".to_string());
replacements.insert("as".to_string(), "gis".to_string());
replacements.insert("b".to_string(), "ais".to_string());
note = note.to_lowercase();
let mut base = note.to_string().to_lowercase();
let is_major: bool;
if base.chars().last().unwrap().to_lowercase().to_string() == "m" {
base.pop();
is_major = false
} else {
is_major = true
}
if replacements.contains_key(&base) {
base = replacements.get(&base).unwrap().to_string();
}
return if !is_major {
let original_index = tones.iter().position(|&r| r == base).unwrap();
let mut note1 = note.to_string().to_lowercase();
note1.pop().unwrap().to_string();
let note2 = String::from(tones[(original_index + 3) % tones.len()]);
let note3 = String::from(tones[(original_index + 3 + 4) % tones.len()]);
Triad { notes: [note1, note2, note3], kind: String::from("minor") }
} else {
let original_index = tones.iter().position(|&r| r == base).unwrap();
let note1 = note.to_string().to_lowercase();
let note2 = String::from(tones[(original_index + 4) % tones.len()]);
let note3 = String::from(tones[(original_index + 4 + 3) % tones.len()]);
Triad { notes: [note1, note2, note3], kind: String::from("major") }
};
}
#[wasm_bindgen]
pub fn get_triad_json(note: String) -> String {
return String::from(serde_json::to_string(&get_triad(note)).unwrap());
}
#[test]
fn test_c_major() {
let triad = get_triad(String::from("c"));
assert_eq!(triad.kind, "major");
assert_eq!(triad.notes[0], "c");
assert_eq!(triad.notes[1], "e");
assert_eq!(triad.notes[2], "g");
}
#[test]
fn test_g_major() {
let triad = get_triad(String::from("g"));
assert_eq!(triad.kind, "major");
assert_eq!(triad.notes[0], "g");
assert_eq!(triad.notes[1], "h");
assert_eq!(triad.notes[2], "d");
}
#[test]
fn test_g_major_capital() {
let triad = get_triad(String::from("G"));
assert_eq!(triad.kind, "major");
assert_eq!(triad.notes[0], "g");
assert_eq!(triad.notes[1], "h");
assert_eq!(triad.notes[2], "d");
}
#[test]
fn test_h_minor() {
let triad = get_triad(String::from("gm"));
assert_eq!(triad.kind, "minor");
assert_eq!(triad.notes[0], "g");
assert_eq!(triad.notes[1], "ais");
assert_eq!(triad.notes[2], "d");
}
#[test]
fn test_e_minor() {
let triad = get_triad(String::from("em"));
assert_eq!(triad.kind, "minor");
assert_eq!(triad.notes[0], "e");
assert_eq!(triad.notes[1], "g");
assert_eq!(triad.notes[2], "h");
}
#[test]
fn test_e_minor_capital() {
let triad = get_triad(String::from("EM"));
assert_eq!(triad.kind, "minor");
assert_eq!(triad.notes[0], "e");
assert_eq!(triad.notes[1], "g");
assert_eq!(triad.notes[2], "h");
}