euphony_core/pitch/mode/
position.rs

1use crate::pitch::mode::{intervals::ModeIntervals, system::ModeSystem};
2use core::fmt;
3
4#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
5pub struct ModePosition(pub usize, pub ModeSystem);
6
7impl ModePosition {
8    pub const fn position(&self) -> usize {
9        self.0
10    }
11
12    pub const fn system(&self) -> ModeSystem {
13        self.1
14    }
15
16    pub const fn intervals(&self) -> ModeIntervals {
17        (self.1).0[self.0]
18    }
19}
20
21impl fmt::Debug for ModePosition {
22    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23        write!(f, "ModePosition({:?})", self.intervals())
24    }
25}
26
27impl fmt::Display for ModePosition {
28    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29        self.intervals().fmt(f)
30    }
31}
32
33impl core::ops::Deref for ModePosition {
34    type Target = ModeIntervals;
35
36    fn deref(&self) -> &Self::Target {
37        &self.1[self.0]
38    }
39}
40
41impl core::ops::Shr<usize> for ModePosition {
42    type Output = ModePosition;
43
44    fn shr(self, rhs: usize) -> Self::Output {
45        let rhs = rhs % self.system().len();
46        let value = self.position() + rhs;
47        let value = value % self.system().len();
48        Self(value, self.system())
49    }
50}
51
52impl core::ops::ShrAssign<usize> for ModePosition {
53    fn shr_assign(&mut self, rhs: usize) {
54        *self = core::ops::Shr::shr(*self, rhs)
55    }
56}
57
58impl core::ops::Shl<usize> for ModePosition {
59    type Output = ModePosition;
60
61    fn shl(self, rhs: usize) -> Self::Output {
62        let rhs = rhs % self.system().len();
63        let value = self.system().len() + self.position() - rhs;
64        let value = value % self.system().len();
65        Self(value, self.system())
66    }
67}
68
69impl core::ops::ShlAssign<usize> for ModePosition {
70    fn shl_assign(&mut self, rhs: usize) {
71        *self = core::ops::Shl::shl(*self, rhs)
72    }
73}