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
use std::collections::HashMap; 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(); if replacements.contains_key(&base) { base = replacements.get(&base).unwrap().to_string() } return if note.chars().last().unwrap().to_lowercase().to_string() == "m" { base.pop(); 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") } }; } #[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"); }