chordcalc/parsing/
notes.rs

1use core::str::FromStr;
2
3use crate::notes::Note;
4
5use super::Error;
6
7impl FromStr for Note {
8    type Err = Error;
9
10    fn from_str(s: &str) -> Result<Self, Self::Err> {
11        match s {
12            "A" => Ok(Self::A),
13            "B" => Ok(Self::B),
14            "C" => Ok(Self::C),
15            "D" => Ok(Self::D),
16            "E" => Ok(Self::E),
17            "F" => Ok(Self::F),
18            "G" => Ok(Self::G),
19            "DO" => Ok(Self::C),
20            "Do" => Ok(Self::C),
21            "do" => Ok(Self::C),
22            "RE" => Ok(Self::D),
23            "Re" => Ok(Self::D),
24            "re" => Ok(Self::D),
25            "MI" => Ok(Self::E),
26            "Mi" => Ok(Self::E),
27            "mi" => Ok(Self::E),
28            "FA" => Ok(Self::F),
29            "Fa" => Ok(Self::F),
30            "fa" => Ok(Self::F),
31            "SOL" => Ok(Self::G),
32            "Sol" => Ok(Self::G),
33            "sol" => Ok(Self::G),
34            "LA" => Ok(Self::A),
35            "La" => Ok(Self::A),
36            "la" => Ok(Self::A),
37            "SI" => Ok(Self::B),
38            "Si" => Ok(Self::B),
39            "si" => Ok(Self::B),
40            _ => Err(Error::UnknownNote),
41        }
42    }
43}
44
45#[cfg(test)]
46#[cfg(test)]
47mod tests {
48    use crate::{notes::Note, parsing::Error};
49
50    #[test]
51    fn parse_notes() {
52        let result = &[
53            Note::A,
54            Note::B,
55            Note::C,
56            Note::D,
57            Note::E,
58            Note::F,
59            Note::G,
60        ];
61        for (note, expected) in ["A", "B", "C", "D", "E", "F", "G"]
62            .iter()
63            .zip(result.iter())
64        {
65            let parsed = note.parse();
66            assert_eq!(parsed, Ok(*expected));
67        }
68    }
69    #[test]
70    fn parse_romance_notes() {
71        let result = &[
72            Note::A,
73            Note::B,
74            Note::C,
75            Note::D,
76            Note::E,
77            Note::F,
78            Note::G,
79        ];
80        for (note, expected) in ["La", "Si", "Do", "Re", "Mi", "Fa", "Sol"]
81            .iter()
82            .zip(result.iter())
83        {
84            let parsed = note.parse();
85            assert_eq!(parsed, Ok(*expected));
86            let parsed = note.to_uppercase().parse();
87            assert_eq!(parsed, Ok(*expected));
88            let parsed = note.to_ascii_lowercase().parse();
89            assert_eq!(parsed, Ok(*expected));
90        }
91    }
92    #[test]
93    fn parse_unexisting_notes() {
94        for note in &["H", "ABC"] {
95            let parsed: Result<Note, Error> = note.parse();
96            assert_eq!(parsed, Err(Error::UnknownNote));
97        }
98    }
99}