rstmt_core/pitch/impls/
pitch_ops.rs

1/*
2    Appellation: pitch_ops <impl>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use crate::{Pitch, PitchMod, PitchTy, PyMod};
6use num::{Num, One, Zero};
7
8macro_rules! impl_interval_method {
9    (@impl $trait:ident.$call:ident) => {
10        paste::paste! {
11            pub fn [<$call _interval>]<T>(&self, rhs: T) -> Self where i8: ::core::ops::$trait<T, Output = PitchTy> {
12                let p = ::core::ops::$trait::$call(*self.get(), rhs);
13                Self::new(p)
14            }
15        }
16    };
17    ($($trait:ident.$call:ident),* $(,)?) => {
18        $(
19            impl_interval_method!(@impl $trait.$call);
20        )*
21    };
22}
23
24impl Pitch {
25    impl_interval_method!(Add.add, Div.div, Mul.mul, Rem.rem, Sub.sub);
26}
27
28wrapper_ops!(Pitch::<PitchTy>: Add.add, Div.div, Mul.mul, Rem.rem, Sub.sub);
29
30wrapper_unop!(Pitch impls Neg.neg, Not.not);
31
32impl PitchMod for Pitch {
33    type Output = Self;
34
35    fn pitchmod(&self) -> Self::Output {
36        Self(self.0.pymod(Self::MOD))
37    }
38}
39
40impl One for Pitch {
41    fn one() -> Self {
42        Self(PitchTy::one())
43    }
44}
45
46impl Zero for Pitch {
47    fn zero() -> Self {
48        Self(PitchTy::zero())
49    }
50
51    fn is_zero(&self) -> bool {
52        self.0.is_zero()
53    }
54}
55
56impl Num for Pitch {
57    type FromStrRadixErr = <PitchTy as Num>::FromStrRadixErr;
58
59    fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
60        PitchTy::from_str_radix(s, radix).map(Self)
61    }
62}