rstmt_core/notes/impls/
impl_aspn.rs

1/*
2    Appellation: impl_aspn <module>
3    Created At: 2025.12.20:08:16:03
4    Contrib: @FL03
5*/
6use crate::notes::aspn::Aspn;
7use crate::octave::Octave;
8use rstmt_traits::PitchMod;
9
10impl Aspn {
11    pub fn new(class: usize, Octave(octave): Octave) -> Self {
12        Self {
13            class,
14            octave: Octave(octave),
15        }
16    }
17    /// returns a new note from a pitch value
18    pub fn from_pitch(pitch: usize) -> Self {
19        Self::new(pitch.pmod(), Octave(4))
20    }
21    /// returns a copy to the index of the note's class
22    pub const fn class(&self) -> usize {
23        self.class
24    }
25    /// returns a mutable reference to the index of the note's class
26    pub fn class_mut(&mut self) -> &mut usize {
27        &mut self.class
28    }
29    /// returns a copy to the octave of the note
30    pub const fn octave(&self) -> Octave {
31        self.octave
32    }
33    /// returns a mutable reference to the current octave
34    pub const fn octave_mut(&mut self) -> &mut Octave {
35        &mut self.octave
36    }
37    /// set the pitch class of the note
38    pub fn set_class(&mut self, class: usize) -> &mut Self {
39        self.class = class.pmod();
40        self
41    }
42    /// set the octave of the note
43    pub fn set_octave(&mut self, octave: Octave) -> &mut Self {
44        self.octave = octave;
45        self
46    }
47    /// consumes the current instance to create another with the given pitch class
48    pub fn with_class(self, class: usize) -> Self {
49        Self { class, ..self }
50    }
51    /// consumes the current instance to create another with the given octave
52    pub fn with_octave(self, octave: Octave) -> Self {
53        Self { octave, ..self }
54    }
55}
56
57impl core::fmt::Display for Aspn {
58    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
59        write!(f, "{}.{}", self.class, self.octave)
60    }
61}
62
63impl PartialEq<usize> for Aspn {
64    fn eq(&self, other: &usize) -> bool {
65        self.class() == *other
66    }
67}
68
69impl PartialEq<Aspn> for usize {
70    fn eq(&self, other: &Aspn) -> bool {
71        *self == other.class()
72    }
73}
74
75impl PartialOrd<usize> for Aspn {
76    fn partial_cmp(&self, other: &usize) -> Option<core::cmp::Ordering> {
77        self.class().partial_cmp(other)
78    }
79}
80
81impl PartialOrd<Aspn> for usize {
82    fn partial_cmp(&self, other: &Aspn) -> Option<core::cmp::Ordering> {
83        self.partial_cmp(&other.class())
84    }
85}
86
87impl core::ops::Add<Aspn> for Aspn {
88    type Output = Self;
89
90    fn add(self, rhs: Aspn) -> Self::Output {
91        let class = (self.class + rhs.class).pmod();
92        let octave = self.octave + rhs.octave;
93
94        Self::new(class, octave)
95    }
96}
97
98impl core::ops::AddAssign<Aspn> for Aspn {
99    fn add_assign(&mut self, rhs: Aspn) {
100        self.class += rhs.class;
101        self.octave += rhs.octave;
102    }
103}
104
105impl core::ops::Add<usize> for Aspn {
106    type Output = Self;
107
108    fn add(self, rhs: usize) -> Self::Output {
109        Self::new(self.class + rhs, self.octave)
110    }
111}
112
113impl core::ops::AddAssign<usize> for Aspn {
114    fn add_assign(&mut self, rhs: usize) {
115        self.class = (self.class + rhs).pmod();
116    }
117}
118
119impl core::ops::Sub<usize> for Aspn {
120    type Output = Self;
121
122    fn sub(self, rhs: usize) -> Self::Output {
123        let class = self.class as isize - rhs as isize;
124        Self {
125            class: class.pmod() as usize,
126            ..self
127        }
128    }
129}
130
131impl core::ops::SubAssign<usize> for Aspn {
132    fn sub_assign(&mut self, rhs: usize) {
133        self.class = (self.class as isize - rhs as isize).pmod() as usize;
134    }
135}
136
137macro_rules! impl_note_from {
138    ($($t:ty),*) => {
139        $(
140            impl From<$t> for Aspn {
141                fn from(class: $t) -> Self {
142                    Self::from_pitch(class.pmod() as usize)
143                }
144            }
145
146            impl From<($t, $crate::octave::Octave)> for Aspn {
147                fn from((class, octave): ($t, $crate::octave::Octave)) -> Self {
148                    Self::new(class.pmod() as usize, octave)
149                }
150            }
151        )*
152    };
153}
154
155impl_note_from!(
156    usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128
157);