resonata/notes/name/
utils.rs

1use std::{fmt::{self, Display, Formatter, Debug}, str::FromStr, ops::{Add, Sub, AddAssign, SubAssign}};
2use super::super::*;
3
4impl From<u8> for NoteName {
5    fn from(value: u8) -> Self {
6        match value % 7 {
7            0 => C,
8            1 => D,
9            2 => E,
10            3 => F,
11            4 => G,
12            5 => A,
13            6 => B,
14            _ => unreachable!(),
15        }
16    }
17}
18
19impl From<NoteName> for u8 {
20    fn from(name: NoteName) -> Self {
21        match name {
22            C => 0,
23            D => 2,
24            E => 4,
25            F => 5,
26            G => 7,
27            A => 9,
28            B => 11,
29        }
30    }
31}
32
33impl Add<u8> for NoteName {
34    type Output = Self;
35
36    fn add(self, n: u8) -> Self::Output {
37        Self::from(u8::from(self) + n % 6)
38    }
39}
40
41impl AddAssign<u8> for NoteName {
42    fn add_assign(&mut self, n: u8) {
43        *self = Self::from(u8::from(*self) + n % 6)
44    }
45}
46
47impl Sub<u8> for NoteName {
48    type Output = Self;
49
50    fn sub(self, n: u8) -> Self::Output {
51        Self::from((u8::from(self) as i8 - n as i8).abs() as u8 % 6)
52    }
53}
54
55impl SubAssign<u8> for NoteName {
56    fn sub_assign(&mut self, n: u8) {
57        *self = Self::from((u8::from(*self) as i8 - n as i8).abs() as u8 % 6)
58    }
59}
60
61impl FromStr for NoteName {
62    type Err = ResonataError;
63    
64    fn from_str(s: &str) -> Result<Self, Self::Err> {
65        match s.to_ascii_lowercase().as_str() {
66            "c" => Ok(C),
67            "d" => Ok(D),
68            "e" => Ok(E),
69            "f" => Ok(F),
70            "g" => Ok(G),
71            "a" => Ok(A),
72            "b" => Ok(B),
73            _ => nope!(InvalidNoteName)
74        }
75    }
76}
77
78impl Display for NoteName {
79    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
80        let token = match self {
81            C => "C",
82            D => "D",
83            E => "E",
84            F => "F",
85            G => "G",
86            A => "A",
87            B => "B",
88        };
89        write!(f, "{}", token)
90    }   
91}
92
93impl Debug for NoteName {
94    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
95        write!(f, "{}", self.to_string())
96    }   
97}