1use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};
2
3use arkley_traits::Power;
4
5use crate::{StandardForm,ParsingNumberError};
6
7#[derive(Debug,PartialEq)]
11pub enum Number {
12 Decimal(f64),
14 StandardForm(StandardForm),
16}
17
18impl PartialOrd<Number> for Number {
19 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
20 match (self, other) {
21 (Number::Decimal(a), Number::Decimal(b)) => a.partial_cmp(b),
22 (Number::StandardForm(a), Number::StandardForm(b)) => a.partial_cmp(b),
23 (Number::StandardForm(a), Number::Decimal(b)) => a.partial_cmp(b),
24 (Number::Decimal(a), Number::StandardForm(b)) => {
25 let rhs : StandardForm = (*a).into();
26 rhs.partial_cmp(b)
27 },
28 }
29 }
30}
31
32impl std::fmt::Display for Number {
33 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
34 match self {
35 Number::Decimal(float) => write!(f,"{}",float),
36 Number::StandardForm(sf) => write!(f,"{}",sf),
37 }
38 }
39}
40
41impl TryFrom<&str> for Number {
42 type Error = ParsingNumberError;
43 fn try_from(value : &str) -> Result<Self, Self::Error> {
44 let into_f64 = value.parse::<f64>();
45 if let Ok(float) = into_f64 {
46 return Ok(Number::Decimal(float));
47 }
48
49 let into_sf = StandardForm::try_from(value);
50
51 if let Ok(standard_form) = into_sf{
52 return Ok(Number::StandardForm(standard_form));
53 }
54
55 Err(ParsingNumberError(into_f64.unwrap_err(),into_sf.unwrap_err()))
56 }
57}
58
59impl Power for Number {
60 type Output = Number;
61
62 fn to_the_power_of(self, other: Number) -> Self::Output {
63 match (self, other) {
64 (Number::Decimal(a), Number::Decimal(b)) => Number::Decimal(a.to_the_power_of(b)),
65 _ => todo!("")
66 }
67 }
68}
69
70impl Add for Number {
71 type Output = Number;
72
73 fn add(self,other : Number) -> Self::Output {
74 use crate::Number::Decimal;
75 match (self,other) {
76 (Decimal(f1),Decimal(f2)) => Decimal(f1 + f2),
77 (Number::StandardForm(sf1),Number::StandardForm(sf2)) => Number::StandardForm(sf1 + sf2),
78 (Number::StandardForm(sf1),Number::Decimal(f2)) => Number::StandardForm(sf1 + f2),
79 (Number::Decimal(f1), Number::StandardForm(sf2)) => {
80 let rhs : StandardForm = f1.into();
81 Number::StandardForm(rhs + sf2)
82 }
83 }
84 }
85}
86
87impl Sub for Number {
88 type Output = Number;
89
90 fn sub(self,other : Number) -> Self::Output {
91 match (self,other) {
92 (Number::Decimal(f1),Number::Decimal(f2)) => Number::Decimal(f1 - f2),
93 (Number::StandardForm(sf1),Number::StandardForm(sf2)) => Number::StandardForm(sf1 - sf2),
94 (Number::StandardForm(sf1),Number::Decimal(f2)) => Number::StandardForm(sf1 - f2),
95 (Number::Decimal(f1), Number::StandardForm(sf2)) => {
96 let rhs : StandardForm = f1.into();
97 Number::StandardForm(rhs - sf2)
98 }
99 }
100 }
101}
102
103impl Mul for Number {
104 type Output = Number;
105
106 fn mul(self,other : Number) -> Self::Output {
107 match (self,other) {
108 (Number::Decimal(f1),Number::Decimal(f2)) => Number::Decimal(f1 * f2),
109 (Number::StandardForm(sf1),Number::StandardForm(sf2)) => Number::StandardForm(sf1 * sf2),
110 (Number::StandardForm(sf1),Number::Decimal(f2)) => Number::StandardForm(sf1 * f2),
111 (Number::Decimal(f1), Number::StandardForm(sf2)) => {
112 let rhs : StandardForm = f1.into();
113 Number::StandardForm(rhs * sf2)
114 }
115 }
116 }
117}
118
119impl Div for Number {
120 type Output = Number;
121
122 fn div(self,other : Number) -> Self::Output {
123 use crate::Number::Decimal;
124 match (self,other) {
125 (Decimal(f1),Decimal(f2)) => Number::Decimal(f1 / f2),
126 (Number::StandardForm(sf1),Number::StandardForm(sf2)) => Number::StandardForm(sf1 / sf2),
127 (Number::StandardForm(sf1),Number::Decimal(f2)) => Number::StandardForm(sf1 / f2),
128 (Number::Decimal(f1), Number::StandardForm(sf2)) => {
129 let rhs : StandardForm = f1.into();
130 Number::StandardForm(rhs / sf2)
131 }
132 }
133 }
134}
135
136impl AddAssign for Number {
137 fn add_assign(&mut self, other: Number) {
138 let temp_self = std::mem::replace(self, Number::Decimal(0.0)); match (temp_self, other) {
141 (Number::Decimal(f1), Number::Decimal(f2)) => *self = Number::Decimal(f1 + f2),
142 (Number::StandardForm(sf1), Number::StandardForm(sf2)) => *self = Number::StandardForm(sf1 + sf2),
143 (Number::StandardForm(sf1), Number::Decimal(f2)) => *self = Number::StandardForm(sf1 + f2),
144 (Number::Decimal(f1), Number::StandardForm(sf2)) => {
145 let rhs: StandardForm = (f1).into();
146 *self = Number::StandardForm(rhs + sf2);
147 }
148 }
149 }
150}
151
152impl SubAssign for Number {
153 fn sub_assign(&mut self, other: Number) {
154 let temp_self = std::mem::replace(self, Number::Decimal(0.0)); match (temp_self, other) {
157 (Number::Decimal(f1), Number::Decimal(f2)) => *self = Number::Decimal(f1 - f2),
158 (Number::StandardForm(sf1), Number::StandardForm(sf2)) => *self = Number::StandardForm(sf1 - sf2),
159 (Number::StandardForm(sf1), Number::Decimal(f2)) => *self = Number::StandardForm(sf1 - f2),
160 (Number::Decimal(f1), Number::StandardForm(sf2)) => {
161 let rhs: StandardForm = (f1).into();
162 *self = Number::StandardForm(rhs - sf2);
163 }
164 }
165 }
166}
167
168impl MulAssign for Number {
169 fn mul_assign(&mut self, other: Number) {
170 let temp_self = std::mem::replace(self, Number::Decimal(0.0)); match (temp_self, other) {
173 (Number::Decimal(f1), Number::Decimal(f2)) => *self = Number::Decimal(f1 * f2),
174 (Number::StandardForm(sf1), Number::StandardForm(sf2)) => *self = Number::StandardForm(sf1 * sf2),
175 (Number::StandardForm(sf1), Number::Decimal(f2)) => *self = Number::StandardForm(sf1 * f2),
176 (Number::Decimal(f1), Number::StandardForm(sf2)) => {
177 let rhs: StandardForm = (f1).into();
178 *self = Number::StandardForm(rhs * sf2);
179 }
180 }
181 }
182}
183
184impl DivAssign for Number {
185 fn div_assign(&mut self, other: Number) {
186 let temp_self = std::mem::replace(self, Number::Decimal(0.0)); match (temp_self, other) {
188 (Number::Decimal(f1), Number::Decimal(f2)) => *self = Number::Decimal(f1 / f2),
189 (Number::StandardForm(sf1), Number::StandardForm(sf2)) => *self = Number::StandardForm(sf1 / sf2),
190 (Number::StandardForm(sf1), Number::Decimal(f2)) => *self = Number::StandardForm(sf1 / f2),
191 (Number::Decimal(f1), Number::StandardForm(sf2)) => {
192 let rhs: StandardForm = (f1).into();
193 *self = Number::StandardForm(rhs / sf2);
194 }
195 }
196 }
197}
198
199macro_rules! primitives {
200 (eq => $($t : ty),*) => {
201 $(
202 impl PartialEq<$t> for Number {
203 fn eq(&self, other: &$t) -> bool {
204 match self {
205 Number::Decimal(f) => f == &(*other as f64),
206 Number::StandardForm(sf) => sf == other,
207 }
208 }
209 }
210 )*
211 };
212 (ord => $($t : ty),*) => {
213 $(
214 impl PartialOrd<$t> for Number {
215 fn partial_cmp(&self, other: &$t) -> Option<std::cmp::Ordering> {
216 match self {
217 Number::Decimal(f) => f.partial_cmp(&(*other as f64)),
218 Number::StandardForm(sf) => sf.partial_cmp(other)
219 }
220 }
221 }
222 )*
223 };
224
225 (add => $($t : ty),*) => {
226 $(
227 impl Add<$t> for Number {
228 type Output = Self;
229 fn add(self, other: $t) -> Self {
230 match self {
231 Number::Decimal(f) => Number::Decimal(f + other as f64),
232 Number::StandardForm(sf) => Number::StandardForm(sf + other),
233 }
234 }
235 }
236
237 impl AddAssign<$t> for Number {
238 fn add_assign(&mut self, other: $t) {
239 *self += Number::Decimal(other as f64)
240 }
241 }
242 )*
243 };
244
245 (sub => $($t : ty),*) => {
246 $(
247 impl Sub<$t> for Number {
248 type Output = Self;
249 fn sub(self, other: $t) -> Self {
250 match self {
251 Number::Decimal(f) => Number::Decimal(f - other as f64),
252 Number::StandardForm(sf) => Number::StandardForm(sf - other),
253 }
254 }
255 }
256
257 impl SubAssign<$t> for Number {
258 fn sub_assign(&mut self, other: $t) {
259 *self -= Number::Decimal(other as f64)
260 }
261 }
262 )*
263 };
264 (mul => $($t : ty),*) => {
265 $(
266 impl Mul<$t> for Number {
267 type Output = Self;
268 fn mul(self, other: $t) -> Self {
269 match self {
270 Number::Decimal(f) => Number::Decimal(f * other as f64),
271 Number::StandardForm(sf) => Number::StandardForm(sf * other),
272 }
273 }
274 }
275
276 impl MulAssign<$t> for Number {
277 fn mul_assign(&mut self, other: $t) {
278 *self *= Number::Decimal(other as f64)
279 }
280 }
281 )*
282 };
283 (div => $($t : ty),*) => {
284 $(
285 impl Div<$t> for Number {
286 type Output = Self;
287 fn div(self, other: $t) -> Self {
288 match self {
289 Number::Decimal(f) => Number::Decimal(f / other as f64),
290 Number::StandardForm(sf) => Number::StandardForm(sf / other),
291 }
292 }
293 }
294
295 impl DivAssign<$t> for Number {
296 fn div_assign(&mut self, other: $t) {
297 *self /= Number::Decimal(other as f64)
298 }
299 }
300 )*
301 };
302 (operations => $($t:ty),*) => {
303 $(
304 primitives!(add => $t);
305 primitives!(sub => $t);
306 primitives!(mul => $t);
307 primitives!(div => $t);
308 )*
309 }
310}
311
312primitives!(eq => u8,u16,u32,u64,i8,i16,i32,i64,f32,f64);
313primitives!(ord => u8,u16,u32,u64,i8,i16,i32,i64,f32,f64);
314primitives!(operations => i8, i16, i32, i64, u8, u16, u32, u64,f32,f64);
315
316#[cfg(test)]
317mod test {
318 use super::*;
319 #[test]
320 fn test_addition() {
321 let num1 = Number::Decimal(2.5);
322 let num2 = Number::Decimal(3.5);
323 let result = num1 + num2;
324 assert_eq!(result, Number::Decimal(6.0));
325 }
326
327 #[test]
329 fn test_subtraction() {
330 let num1 = Number::Decimal(5.5);
331 let num2 = Number::Decimal(3.5);
332 let result = num1 - num2;
333 assert_eq!(result, Number::Decimal(2.0));
334 }
335
336 #[test]
338 fn test_multiplication() {
339 let num1 = Number::Decimal(2.5);
340 let num2 = Number::Decimal(3.0);
341 let result = num1 * num2;
342 assert_eq!(result, Number::Decimal(7.5));
343 }
344
345 #[test]
347 fn test_division() {
348 let num1 = Number::Decimal(10.0);
349 let num2 = Number::Decimal(2.0);
350 let result = num1 / num2;
351 assert_eq!(result, Number::Decimal(5.0));
352 }
353
354 #[test]
356 fn test_addition_assignment() {
357 let mut num = Number::Decimal(3.0);
358 let num2 = Number::Decimal(2.0);
359 num += num2;
360 assert_eq!(num, Number::Decimal(5.0));
361 }
362
363 #[test]
365 fn test_subtraction_assignment() {
366 let mut num = Number::Decimal(5.0);
367 let num2 = Number::Decimal(3.0);
368 num -= num2;
369 assert_eq!(num, Number::Decimal(2.0));
370 }
371
372 #[test]
374 fn test_multiplication_assignment() {
375 let mut num = Number::Decimal(2.5);
376 let num2 = Number::Decimal(3.0);
377 num *= num2;
378 assert_eq!(num, Number::Decimal(7.5));
379 }
380
381 #[test]
383 fn test_division_assignment() {
384 let mut num = Number::Decimal(10.0);
385 let num2 = Number::Decimal(2.0);
386 num /= num2;
387 assert_eq!(num, Number::Decimal(5.0));
388 }
389
390 #[test]
391 fn test_display_decimal() {
392 let number = Number::Decimal(3.14);
393 assert_eq!(format!("{}", number), "3.14");
394 assert_eq!(number.to_string(), "3.14");
395 }
396
397 #[test]
398 fn test_try_from_valid_number() {
399 let input = "3.14";
401 let result = Number::try_from(input);
402 assert!(result.is_ok());
403
404 if let Ok(Number::Decimal(value)) = result {
406 assert_eq!(value, 3.14);
407 } else {
408 assert!(false, "Expected Ok(Number::Decimal(_)), but got an error.");
409 }
410 }
411
412 #[test]
413 fn test_try_from_invalid_number() {
414 let input = "abc"; let result = Number::try_from(input);
417 assert!(result.is_err());
418
419 if let Err(_) = result {
421 } else {
422 assert!(false, "Expected Err(ParseFloatError), but got a success.");
423 }
424 }
425
426 #[test]
427 fn test_try_from_empty_string() {
428 let input = "";
430 let result = Number::try_from(input);
431 assert!(result.is_err());
432
433 if let Err(_) = result {
435 } else {
436 assert!(false, "Expected Err(ParseFloatError), but got a success.");
437 }
438 }
439}