music_note/scale/
degree.rs1use crate::{
2 midi::MidiNote,
3 note::{Accidental, Note},
4 pitch::Pitch,
5 Interval, Natural,
6};
7
8pub trait Degree {
9 type State;
10
11 fn state(self) -> Self::State;
12
13 fn degree(self, state: &mut Self::State, interval: Interval) -> Self;
14}
15
16impl<A> Degree for Note<A>
17where
18 A: Accidental,
19{
20 type State = Natural;
21
22 fn state(self) -> Self::State {
23 self.natural()
24 }
25
26 fn degree(self, state: &mut Self::State, interval: Interval) -> Self {
27 let pitch = Pitch::from(self.clone()).add_interval(interval);
28 let accidental = A::from_pitch(*state, pitch);
29 let note = Self::new(*state, accidental);
30
31 *state = *state + 1;
32 note
33 }
34}
35
36impl Degree for Pitch {
37 type State = ();
38
39 fn state(self) -> Self::State {}
40
41 fn degree(self, _state: &mut Self::State, interval: Interval) -> Self {
42 self + interval
43 }
44}
45
46impl Degree for MidiNote {
47 type State = ();
48
49 fn state(self) -> Self::State {}
50
51 fn degree(self, _state: &mut Self::State, interval: Interval) -> Self {
52 self + interval
53 }
54}