notation_core/
tone.rs

1use std::fmt::Display;
2
3use serde::{Deserialize, Serialize};
4
5use super::note::Note;
6
7#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
8pub enum Tone {
9    None,
10    Single(Note),
11    Double(Note, Note),
12    Triple(Note, Note, Note),
13    Tetra(Note, Note, Note, Note),
14    Penta(Note, Note, Note, Note, Note),
15    Hexa(Note, Note, Note, Note, Note, Note),
16}
17
18impl Tone {
19    /// Returns `true` if the tone is [`None`].
20    pub fn is_none(&self) -> bool {
21        matches!(self, Self::None)
22    }
23}
24impl Display for Tone {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        match *self {
27            Tone::None => write!(f, "<Tone>()"),
28            Tone::Single(n1) => write!(f, "<Tone>({})", n1),
29            Tone::Double(n1, n2) => write!(f, "<Tone>({}, {})", n1, n2),
30            Tone::Triple(n1, n2, n3) => write!(f, "<Tone>({}, {}, {})", n1, n2, n3),
31            Tone::Tetra(n1, n2, n3, n4) => {
32                write!(f, "<Tone>({}, {}, {}, {})", n1, n2, n3, n4)
33            }
34            Tone::Penta(n1, n2, n3, n4, n5) => {
35                write!(f, "<Tone>({}, {}, {}, {}, {})", n1, n2, n3, n4, n5)
36            }
37            Tone::Hexa(n1, n2, n3, n4, n5, n6) => {
38                write!(f, "<Tone>({}, {}, {}, {}, {}, {})", n1, n2, n3, n4, n5, n6)
39            }
40        }
41    }
42}
43
44impl From<()> for Tone {
45    fn from(_: ()) -> Self {
46        Self::None
47    }
48}
49
50impl From<Note> for Tone {
51    fn from(v: Note) -> Self {
52        Tone::Single(v)
53    }
54}
55
56impl From<(Note, Note)> for Tone {
57    fn from(v: (Note, Note)) -> Self {
58        Tone::Double(v.0, v.1)
59    }
60}
61
62impl From<(Note, Note, Note)> for Tone {
63    fn from(v: (Note, Note, Note)) -> Self {
64        Tone::Triple(v.0, v.1, v.2)
65    }
66}
67
68impl From<(Note, Note, Note, Note)> for Tone {
69    fn from(v: (Note, Note, Note, Note)) -> Self {
70        Tone::Tetra(v.0, v.1, v.2, v.3)
71    }
72}
73
74impl From<(Note, Note, Note, Note, Note)> for Tone {
75    fn from(v: (Note, Note, Note, Note, Note)) -> Self {
76        Tone::Penta(v.0, v.1, v.2, v.3, v.4)
77    }
78}
79
80impl From<(Note, Note, Note, Note, Note, Note)> for Tone {
81    fn from(v: (Note, Note, Note, Note, Note, Note)) -> Self {
82        Tone::Hexa(v.0, v.1, v.2, v.3, v.4, v.5)
83    }
84}
85
86impl From<Vec<Note>> for Tone {
87    fn from(v: Vec<Note>) -> Self {
88        match v.len() {
89            0 => Self::None,
90            1 => Self::from(v[0]),
91            2 => Self::from((v[0], v[1])),
92            3 => Self::from((v[0], v[1], v[2])),
93            4 => Self::from((v[0], v[1], v[2], v[3])),
94            5 => Self::from((v[0], v[1], v[2], v[3], v[4])),
95            6 => Self::from((v[0], v[1], v[2], v[3], v[4], v[5])),
96            _ => {
97                println!("ToneNote lost: {}", v.len() - 6);
98                Self::from((v[0], v[1], v[2], v[3], v[4], v[5]))
99            }
100        }
101    }
102}
103
104impl From<Vec<Option<Note>>> for Tone {
105    fn from(v: Vec<Option<Note>>) -> Self {
106        let notes = v
107            .iter()
108            .filter(|x| x.is_some())
109            .map(|x| x.unwrap())
110            .collect::<Vec<Note>>();
111        notes.into()
112    }
113}
114
115impl Tone {
116    pub fn get_notes(&self) -> Vec<Note> {
117        match *self {
118            Self::None => vec![],
119            Self::Single(n1) => vec![n1],
120            Self::Double(n1, n2) => vec![n1, n2],
121            Self::Triple(n1, n2, n3) => vec![n1, n2, n3],
122            Self::Tetra(n1, n2, n3, n4) => vec![n1, n2, n3, n4],
123            Self::Penta(n1, n2, n3, n4, n5) => vec![n1, n2, n3, n4, n5],
124            Self::Hexa(n1, n2, n3, n4, n5, n6) => vec![n1, n2, n3, n4, n5, n6],
125        }
126    }
127}
128
129impl From<Tone> for Vec<Note> {
130    fn from(v: Tone) -> Self {
131        v.get_notes()
132    }
133}