rstmt_core/pitch/
pitch.rs1use rstmt_traits::Numerical;
7
8#[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
13#[cfg_attr(
14 feature = "serde",
15 derive(serde::Deserialize, serde::Serialize),
16 serde(transparent)
17)]
18#[repr(transparent)]
19pub struct Pitch<T = f64>(pub T);
20
21pub trait RawPitch
25where
26 Self: Send + Sync + core::fmt::Debug + core::fmt::Display + PartialEq + PartialOrd,
27{
28 private! {}
29}
30pub trait NumPitch: RawPitch + Numerical {}
33
34pub trait AsPitch<T>
36where
37 T: RawPitch,
38{
39 fn as_pitch(&self) -> Pitch<T>;
40}
41pub trait IntoPitch<T>
43where
44 T: RawPitch,
45{
46 fn into_pitch(self) -> Pitch<T>;
47
48 private! {}
49}
50pub trait Pitched<T>
52where
53 T: RawPitch,
54{
55 fn pitch(&self) -> Pitch<&T>;
56}
57
58impl<U, T> AsPitch<T> for U
62where
63 U: Clone + IntoPitch<T>,
64 T: RawPitch,
65{
66 fn as_pitch(&self) -> Pitch<T> {
67 self.clone().into_pitch()
68 }
69}
70
71impl<U, T> IntoPitch<T> for U
72where
73 U: Into<Pitch<T>>,
74 T: RawPitch,
75{
76 fn into_pitch(self) -> Pitch<T> {
77 self.into()
78 }
79
80 seal! {}
81}
82
83impl<T> RawPitch for &T
84where
85 T: RawPitch,
86{
87 seal! {}
88}
89
90impl<T> RawPitch for &mut T
91where
92 T: RawPitch,
93{
94 seal! {}
95}
96
97impl<T> NumPitch for T where T: RawPitch + Numerical {}
98
99macro_rules! impl_raw_pitch {
100 ($($tgt:ty),* $(,)?) => {
101 $(
102 impl RawPitch for $tgt {
103 seal! {}
104 }
105 )*
106 };
107}
108
109impl_raw_pitch! {
110 u8, u16, u32, u64, u128, usize,
111 i8, i16, i32, i64, i128, isize,
112 f32, f64
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn test_pitch_creation() {
121 let a4 = Pitch(440f64);
122 assert_eq! { a4, 440.0 }
123 }
124}