1use core::{cmp::Ordering, ops::*};
6
7#[derive(Clone, Copy, Debug)]
10pub enum Position {
11 Degrees(f64),
13 Rotations(f64),
15 Counts(i64),
17}
18
19impl Position {
20 pub const fn from_degrees(position: f64) -> Self {
22 Self::Degrees(position)
23 }
24
25 pub const fn from_rotations(position: f64) -> Self {
27 Self::Rotations(position)
28 }
29
30 pub const fn from_counts(position: i64) -> Self {
32 Self::Counts(position)
33 }
34
35 pub fn into_degrees(self) -> f64 {
37 match self {
38 Self::Degrees(num) => num,
39 Self::Rotations(num) => num * 360.0,
40 Self::Counts(num) => num as f64 * (360.0 / 4096.0),
41 }
42 }
43
44 pub fn into_rotations(self) -> f64 {
46 match self {
47 Self::Degrees(num) => num / 360.0,
48 Self::Rotations(num) => num,
49 Self::Counts(num) => num as f64 * 4096.0,
50 }
51 }
52
53 pub fn into_counts(self) -> i64 {
55 match self {
56 Self::Degrees(num) => (num * 4096.0 / 360.0) as i64,
57 Self::Rotations(num) => (num * 4096.0) as i64,
58 Self::Counts(num) => num,
59 }
60 }
61}
62
63impl Add for Position {
64 type Output = Self;
65
66 fn add(self, rhs: Self) -> Self::Output {
67 Self::from_degrees(self.into_degrees() + rhs.into_degrees())
68 }
69}
70
71impl AddAssign for Position {
72 fn add_assign(&mut self, rhs: Self) {
73 *self = *self + rhs;
74 }
75}
76
77impl Sub for Position {
78 type Output = Self;
79
80 fn sub(self, rhs: Self) -> Self::Output {
81 Self::from_degrees(self.into_degrees() - rhs.into_degrees())
82 }
83}
84
85impl SubAssign for Position {
86 fn sub_assign(&mut self, rhs: Self) {
87 *self = *self - rhs;
88 }
89}
90
91impl Mul<Self> for Position {
92 type Output = Self;
93
94 fn mul(self, rhs: Self) -> Self::Output {
95 Self::from_degrees(self.into_degrees() * rhs.into_degrees())
96 }
97}
98
99impl MulAssign<Self> for Position {
100 fn mul_assign(&mut self, rhs: Self) {
101 *self = *self * rhs;
102 }
103}
104
105impl Div<Self> for Position {
106 type Output = Self;
107
108 fn div(self, rhs: Self) -> Self::Output {
109 Self::from_degrees(self.into_degrees() / rhs.into_degrees())
110 }
111}
112
113impl DivAssign<Self> for Position {
114 fn div_assign(&mut self, rhs: Self) {
115 *self = *self / rhs;
116 }
117}
118
119impl Rem<Self> for Position {
120 type Output = Self;
121
122 fn rem(self, rhs: Self) -> Self::Output {
123 Self::from_degrees(self.into_degrees() % rhs.into_degrees())
124 }
125}
126
127impl RemAssign<Self> for Position {
128 fn rem_assign(&mut self, rhs: Self) {
129 *self = *self % rhs;
130 }
131}
132
133impl Neg for Position {
134 type Output = Self;
135
136 fn neg(self) -> Self::Output {
137 Self::from_degrees(-self.into_degrees())
138 }
139}
140
141impl PartialEq for Position {
142 fn eq(&self, other: &Self) -> bool {
143 self.into_degrees() == other.into_degrees()
144 }
145}
146
147impl PartialOrd for Position {
148 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
149 self.into_degrees().partial_cmp(&other.into_degrees())
150 }
151}