rstmt_core/intervals/traits/units.rs
1/*
2 Appellation: units <module>
3 Created At: 2025.12.31:17:57:08
4 Contrib: @FL03
5*/
6/// A musical unison is the identity interval in music theory, representing no pitch difference.
7pub trait Unison {
8 /// returns a single unison
9 fn unison() -> Self;
10 /// returns true if the caller's value is equivalent to a single unison.
11 fn is_unison(&self) -> bool
12 where
13 Self: Sized + PartialEq,
14 {
15 *self == Self::unison()
16 }
17}
18/// Similar to the [`One`](num_traits::One) trait, the [`Semitone`] is an identity and unit for
19/// musical contexts.
20pub trait Semitone {
21 /// returns a single semitone
22 fn semitone() -> Self;
23 /// returns true if the caller's value is equivalent to a single semitone.
24 fn is_semitone(&self) -> bool
25 where
26 Self: Sized + PartialEq,
27 {
28 *self == Self::semitone()
29 }
30}
31
32pub trait WholeTone {
33 /// returns a new instance set to the value of a whole tone (2 semitones)
34 fn tone() -> Self;
35}
36
37/*
38 ************* Implementations *************
39*/
40macro_rules! impl_semitone {
41 ($($T:ty),* $(,)?) => {
42 $(impl_semitone! { @impl $T })*
43 };
44 (@impl $T:ty) => {
45 impl $crate::intervals::traits::Unison for $T {
46 fn unison() -> Self {
47 0 as $T
48 }
49 }
50
51 impl $crate::intervals::traits::Semitone for $T {
52 fn semitone() -> Self {
53 1 as $T
54 }
55 }
56
57 impl $crate::intervals::traits::WholeTone for $T {
58 fn tone() -> Self {
59 2 as $T
60 }
61 }
62 };
63}
64
65impl_semitone! {
66 u8, u16, u32, u64, u128, usize,
67 i8, i16, i32, i64, i128, isize,
68 f32, f64,
69}