akkorders 0.1.1

A library and CLI for calculating triads
Documentation
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 mut temp = base.clone();
    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");
}