rstmt_traits/
num.rs

1/*
2    Appellation: num <module>
3    Created At: 2025.12.20:06:02:11
4    Contrib: @FL03
5*/
6use crate::{PitchMod, PyMod};
7use num_traits::{FromPrimitive, One, ToPrimitive, Zero};
8
9pub trait OrderedNum
10where
11    Self: PartialEq + PartialOrd + One + Zero,
12{
13    private! {}
14
15    fn is_positive(&self) -> bool {
16        *self > Self::zero()
17    }
18
19    fn is_negative(&self) -> bool {
20        *self < Self::zero()
21    }
22}
23
24pub trait Numerical
25where
26    Self: OrderedNum
27        + Clone
28        + Copy
29        + Default
30        + FromPrimitive
31        + ToPrimitive
32        + PyMod<Output = Self>
33        + core::fmt::Debug
34        + core::fmt::Display
35        + core::ops::Add<Output = Self>
36        + core::ops::Sub<Output = Self>
37        + core::ops::Mul<Output = Self>
38        + core::ops::Div<Output = Self>
39        + core::ops::Rem<Output = Self>
40        + core::ops::AddAssign
41        + core::ops::DivAssign
42        + core::ops::MulAssign
43        + core::ops::RemAssign
44        + core::ops::SubAssign,
45{
46    private! {}
47
48    fn apply<F, U>(self, f: F) -> U
49    where
50        F: FnOnce(Self) -> U,
51    {
52        f(self)
53    }
54
55    fn abs(self) -> Self
56    where
57        Self: core::ops::Neg<Output = Self>,
58    {
59        if self.is_negative() { -self } else { self }
60    }
61}
62
63pub trait MusicScalar
64where
65    Self: Numerical + crate::PyMod<Output = Self> + crate::PitchMod<Output = Self>,
66{
67    private! {}
68}
69/*
70 ************* Implementations *************
71*/
72
73impl<T> OrderedNum for T
74where
75    T: PartialEq + PartialOrd + One + Zero,
76{
77    seal! {}
78}
79
80impl<T> Numerical for T
81where
82    T: Clone
83        + Copy
84        + Default
85        + PartialEq
86        + PartialOrd
87        + FromPrimitive
88        + ToPrimitive
89        + One
90        + Zero
91        + PitchMod<Output = Self>
92        + PyMod<Output = Self>
93        + core::fmt::Debug
94        + core::fmt::Display
95        + core::ops::Add<Output = Self>
96        + core::ops::Sub<Output = Self>
97        + core::ops::Mul<Output = Self>
98        + core::ops::Div<Output = Self>
99        + core::ops::Rem<Output = Self>
100        + core::ops::AddAssign
101        + core::ops::DivAssign
102        + core::ops::MulAssign
103        + core::ops::RemAssign
104        + core::ops::SubAssign,
105{
106    seal! {}
107}
108
109impl<T> MusicScalar for T
110where
111    T: Numerical + PyMod<Output = Self> + PitchMod<Output = Self>,
112{
113    seal! {}
114}
115
116// macro_rules! numerical {
117//     (impl $trait:ident for { $($T:ty),* $(,)? }) => {
118//         $(impl $trait for $T {})*
119//     };
120// }
121
122// numerical! {
123//     impl Numerical for {
124//         u8, u16, u32, u64, u128, usize,
125//         i8, i16, i32, i64, i128, isize,
126//         f32, f64
127//     }
128// }