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}