rust_music_theory/chord/
quality.rs1use crate::chord::errors::ChordError;
2use lazy_static::lazy_static;
3use regex::{Match, Regex};
4use strum_macros::Display;
5
6lazy_static! {
7 static ref QUALITY_REGEXES: Vec<(Regex, Quality)> = {
8 use Quality::*;
9
10 vec![
11 (
12 Regex::new(r"^(M\s+|M$|(?i)maj|Maj|Major|major)").unwrap(),
13 Major,
14 ),
15 (
16 Regex::new(r"^(m\s+|m$|(?i)min|Min|Minor|minor)").unwrap(),
17 Minor,
18 ),
19 (Regex::new(r"(?i)^(diminished)").unwrap(), Diminished),
20 (Regex::new(r"(?i)^(augmented)").unwrap(), Augmented),
21 (
22 Regex::new(r"(?i)^(half\s*diminished|halfdiminished)").unwrap(),
23 HalfDiminished,
24 ),
25 (Regex::new(r"(?i)^(dominant)").unwrap(), Dominant),
26 (
27 Regex::new(r"(?i)^(sus2\s+|sus2$|suspended2)").unwrap(),
28 Suspended2,
29 ),
30 (
31 Regex::new(r"(?i)^(sus4\s+|sus4$|suspended4)").unwrap(),
32 Suspended4,
33 ),
34 ]
35 };
36}
37
38#[derive(Display, Debug, Clone, Copy, PartialEq)]
40pub enum Quality {
41 Major,
42 Minor,
43 Diminished,
44 Augmented,
45 HalfDiminished,
46 Dominant,
47 Suspended2,
48 Suspended4,
49}
50
51impl Quality {
52 pub fn from_regex(string: &str) -> Result<(Self, Option<Match>), ChordError> {
54 use Quality::*;
55
56 for (regex, quality_enum) in &*QUALITY_REGEXES {
57 let mode = regex.find(string.trim());
58
59 if let Some(quality_match) = mode {
60 return Ok((*quality_enum, Some(quality_match)));
61 };
62 }
63
64 Ok((Major, None))
65 }
66}