music_note/scale/
degree.rs

1use 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}