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