music_note/
interval.rs

1use core::ops::Add;
2
3/// Music interval in semitones.
4#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
5pub struct Interval {
6    semitones: u8,
7}
8
9impl Interval {
10    pub const UNISON: Self = Self::new(0);
11
12    pub const MINOR_SECOND: Self = Self::new(1);
13
14    pub const MAJOR_SECOND: Self = Self::new(2);
15
16    pub const MINOR_THIRD: Self = Self::new(3);
17
18    pub const MAJOR_THIRD: Self = Self::new(4);
19
20    pub const PERFECT_FOURTH: Self = Self::new(5);
21
22    pub const TRITONE: Self = Self::new(6);
23
24    pub const PERFECT_FIFTH: Self = Self::new(7);
25
26    pub const MINOR_SIXTH: Self = Self::new(8);
27    pub const MAJOR_SIXTH: Self = Self::new(9);
28
29    pub const MINOR_SEVENTH: Self = Self::new(10);
30    pub const MAJOR_SEVENTH: Self = Self::new(11);
31
32    pub const THIRTEENTH: Self = Self::new(21);
33
34    pub const fn new(semitones: u8) -> Self {
35        Self { semitones }
36    }
37
38    pub const fn semitones(self) -> u8 {
39        self.semitones
40    }
41}
42
43impl From<u8> for Interval {
44    fn from(semitones: u8) -> Self {
45        Self::new(semitones)
46    }
47}
48
49impl From<Interval> for u8 {
50    fn from(interval: Interval) -> Self {
51        interval.semitones()
52    }
53}
54
55impl Add for Interval {
56    type Output = Self;
57
58    fn add(self, rhs: Self) -> Self {
59        Self::new(self.semitones() + rhs.semitones())
60    }
61}