use std::ops::Add;
use crate::StaffSteps;
const STAFF_POSITION_COUNT: StaffSteps = 7;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum StaffPosition {
CPos,
DPos,
EPos,
FPos,
GPos,
APos,
BPos,
}
impl From<StaffSteps> for StaffPosition {
fn from(n: StaffSteps) -> Self {
use StaffPosition::*;
let v = n % STAFF_POSITION_COUNT;
match v {
0 => CPos,
1 => DPos,
2 => EPos,
3 => FPos,
4 => GPos,
5 => APos,
6 => BPos,
_ => unreachable!(),
}
}
}
impl Add<StaffSteps> for StaffPosition {
type Output = Self;
fn add(self, n: StaffSteps) -> Self {
Self::from(self as StaffSteps + n)
}
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use StaffPosition::*;
use super::*;
#[rstest(
n,
staff_position,
case(0, CPos),
case(1, DPos),
case(2, EPos),
case(3, FPos),
case(4, GPos),
case(5, APos),
case(6, BPos)
)]
fn test_from_int(n: StaffSteps, staff_position: StaffPosition) {
assert_eq!(StaffPosition::from(n), staff_position);
}
#[rstest(
staff_position,
n,
result,
case(CPos, 0, CPos),
case(CPos, 1, DPos),
case(DPos, 2, FPos),
case(CPos, 7, CPos),
case(CPos, 8, DPos),
case(CPos, 14, CPos)
)]
fn test_pitch_class_add_int(
staff_position: StaffPosition,
n: StaffSteps,
result: StaffPosition,
) {
assert_eq!(staff_position + n, result);
}
}