1use std::fmt;
2use std::ops::{Add, AddAssign};
3
4#[derive(Debug, PartialEq, Clone, Copy)]
8pub enum Sum {
9 Integer(i128),
10 Float(f64),
11}
12
13impl Add for Sum {
14 type Output = Self;
15
16 fn add(self, other: Self) -> Self {
18 match (self, other) {
19 (Sum::Integer(a), Sum::Integer(b)) => Sum::Integer(a + b),
20 (Sum::Float(a), Sum::Float(b)) => Sum::Float(a + b),
21 (Sum::Integer(a), Sum::Float(b)) => Sum::Float(a as f64 + b),
22 (Sum::Float(a), Sum::Integer(b)) => Sum::Float(a + b as f64),
23 }
24 }
25}
26
27impl AddAssign for Sum {
28 fn add_assign(&mut self, other: Self) {
30 *self = *self + other;
31 }
32}
33
34impl fmt::Display for Sum {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 Sum::Integer(n) => write!(f, "{n}"),
38 Sum::Float(n) => write!(f, "{n}"),
39 }
40 }
41}
42
43impl fmt::UpperHex for Sum {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 match self {
46 Sum::Integer(n) => fmt::UpperHex::fmt(n, f),
47 Sum::Float(n) => fmt::Display::fmt(n, f),
48 }
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn sum_integer_works() {
58 let a = Sum::Integer(1);
59 let b = Sum::Integer(2);
60 assert_eq!(a + b, Sum::Integer(3));
61
62 let mut c = a;
63 c += b;
64 assert_eq!(c, Sum::Integer(3));
65 }
66
67 #[test]
68 fn sum_float_works() {
69 let a = Sum::Float(0.2);
70 let b = Sum::Float(0.8);
71 assert_eq!(a + b, Sum::Float(1.0));
72 }
73
74 #[test]
75 fn sum_mixed_works() {
76 let a = Sum::Integer(1);
77 let b = Sum::Float(0.2);
78 assert_eq!(a + b, Sum::Float(1.2));
79 assert_eq!(b + a, Sum::Float(1.2));
80 }
81}