rstmt_core/notes/impls/
impl_aspn.rs1use 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 pub fn from_pitch(pitch: usize) -> Self {
19 Self::new(pitch.pmod(), Octave(4))
20 }
21 pub const fn class(&self) -> usize {
23 self.class
24 }
25 pub fn class_mut(&mut self) -> &mut usize {
27 &mut self.class
28 }
29 pub const fn octave(&self) -> Octave {
31 self.octave
32 }
33 pub const fn octave_mut(&mut self) -> &mut Octave {
35 &mut self.octave
36 }
37 pub fn set_class(&mut self, class: usize) -> &mut Self {
39 self.class = class.pmod();
40 self
41 }
42 pub fn set_octave(&mut self, octave: Octave) -> &mut Self {
44 self.octave = octave;
45 self
46 }
47 pub fn with_class(self, class: usize) -> Self {
49 Self { class, ..self }
50 }
51 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);