rstmt_core/pitch/
pitch.rs1use super::{PitchTy, Pitches};
6use crate::PyMod;
7
8#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
11#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
12#[repr(transparent)]
13pub struct Pitch(pub PitchTy);
14
15impl Pitch {
16 pub const MOD: PitchTy = crate::MODULUS;
17
18 pub fn new(pitch: PitchTy) -> Self {
19 Self(pitch)
20 }
21 pub fn into_inner(self) -> PitchTy {
23 self.0
24 }
25 pub const fn get(&self) -> &PitchTy {
27 &self.0
28 }
29 pub fn get_mut(&mut self) -> &mut PitchTy {
31 &mut self.0
32 }
33 pub fn set(&mut self, val: PitchTy) {
35 self.0 = val;
36 }
37}
38
39impl Pitch {
40 pub fn class(&self) -> Pitches {
42 Pitches::try_from_value(self.0.pymod(Self::MOD).abs()).unwrap()
43 }
44 pub fn into_class(self) -> Pitches {
46 self.class()
47 }
48 pub fn map<F>(self, f: F) -> Self
50 where
51 F: Fn(PitchTy) -> PitchTy,
52 {
53 Self(f(self.0))
54 }
55
56 pub fn map_mut<F>(&mut self, mut f: F)
57 where
58 F: FnMut(&mut PitchTy),
59 {
60 f(&mut self.0)
61 }
62 pub fn map_once<F>(self, f: F) -> Self
65 where
66 F: FnOnce(PitchTy) -> PitchTy,
67 {
68 Self(f(self.0))
69 }
70 pub fn abs(self) -> Self {
73 self.map(|p| p.abs())
74 }
75 pub fn absmod(self) -> Self {
77 self.map(|p| p.pymod(Self::MOD).abs())
78 }
79 pub fn pymod(self) -> Self {
83 self.map(|p| p.pymod(Self::MOD))
84 }
85}
86
87impl AsRef<PitchTy> for Pitch {
88 fn as_ref(&self) -> &PitchTy {
89 &self.0
90 }
91}
92
93impl AsMut<PitchTy> for Pitch {
94 fn as_mut(&mut self) -> &mut PitchTy {
95 &mut self.0
96 }
97}
98
99impl core::borrow::Borrow<PitchTy> for Pitch {
100 fn borrow(&self) -> &PitchTy {
101 &self.0
102 }
103}
104
105impl core::borrow::BorrowMut<PitchTy> for Pitch {
106 fn borrow_mut(&mut self) -> &mut PitchTy {
107 &mut self.0
108 }
109}
110
111impl Default for Pitch {
112 fn default() -> Self {
113 Self(super::Natural::default().pitch())
114 }
115}
116
117impl core::ops::Deref for Pitch {
118 type Target = PitchTy;
119
120 fn deref(&self) -> &Self::Target {
121 self.as_ref()
122 }
123}
124
125impl core::ops::DerefMut for Pitch {
126 fn deref_mut(&mut self) -> &mut Self::Target {
127 self.as_mut()
128 }
129}
130
131impl core::fmt::Debug for Pitch {
132 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
133 f.debug_tuple(&self.class().to_string())
134 .field(&self.0)
135 .finish()
136 }
137}
138
139impl core::fmt::Display for Pitch {
140 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
141 write!(f, "{}({})", self.class(), self.0)
142 }
143}
144macro_rules! impl_fmt {
145 (@impl $trait:ident) => {
146 impl ::core::fmt::$trait for Pitch {
147 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
148 ::core::fmt::$trait::fmt(&self.0, f)
149 }
150 }
151 };
152 ($($trait:ident),* $(,)?) => {
153 $(
154 impl_fmt!(@impl $trait);
155 )*
156 };
157}
158
159impl_fmt!(Binary, LowerHex, Octal, UpperHex);
160
161impl From<PitchTy> for Pitch {
162 fn from(pitch: PitchTy) -> Self {
163 Self(pitch)
164 }
165}
166
167impl From<Pitch> for PitchTy {
168 fn from(pitch: Pitch) -> Self {
169 pitch.0
170 }
171}
172
173impl From<Pitches> for Pitch {
174 fn from(pitch: Pitches) -> Self {
175 Self(pitch.value())
176 }
177}
178
179impl From<Pitch> for Pitches {
180 fn from(pitch: Pitch) -> Self {
181 pitch.class()
182 }
183}