pub trait Unison {
fn unison() -> Self;
fn is_unison(&self) -> bool
where
Self: Sized + PartialEq,
{
*self == Self::unison()
}
}
pub trait Semitone {
fn semitone() -> Self;
fn is_semitone(&self) -> bool
where
Self: Sized + PartialEq,
{
*self == Self::semitone()
}
}
pub trait WholeTone {
fn tone() -> Self;
}
macro_rules! impl_semitone {
($($T:ty),* $(,)?) => {
$(impl_semitone! { @impl $T })*
};
(@impl $T:ty) => {
impl $crate::intervals::traits::Unison for $T {
fn unison() -> Self {
0 as $T
}
}
impl $crate::intervals::traits::Semitone for $T {
fn semitone() -> Self {
1 as $T
}
}
impl $crate::intervals::traits::WholeTone for $T {
fn tone() -> Self {
2 as $T
}
}
};
}
impl_semitone! {
u8, u16, u32, u64, u128, usize,
i8, i16, i32, i64, i128, isize,
f32, f64,
}