trading_types/
worth.rs

1use core::ops;
2use std::cmp::{Eq, PartialEq, PartialOrd};
3// use std::cmp::{Ord, Ordering};
4
5use serde::{Deserialize, Serialize};
6
7use crate::{Amount, Price};
8
9/// Worth (cost) = price * amount
10#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialOrd, PartialEq)]
11pub struct Worth(pub f64);
12
13impl Eq for Worth {}
14
15impl From<(Price, Amount)> for Worth {
16    fn from((p, a): (Price, Amount)) -> Self {
17        Self::from_pa(p, a)
18    }
19}
20
21impl Worth {
22    pub fn from_pa(p: Price, a: Amount) -> Self {
23        Worth(p.0 * a.0)
24    }
25}
26
27impl ops::Sub<Worth> for Worth {
28    type Output = Self;
29    fn sub(self, rhs: Worth) -> Self {
30        Worth(self.0 - rhs.0)
31    }
32}
33
34impl ops::Add<Worth> for Worth {
35    type Output = Self;
36    fn add(self, rhs: Worth) -> Self {
37        Worth(self.0 + rhs.0)
38    }
39}
40
41impl ops::AddAssign<Worth> for Worth {
42    fn add_assign(&mut self, rhs: Worth) {
43        self.0 += rhs.0;
44    }
45}
46
47impl ops::SubAssign<Worth> for Worth {
48    fn sub_assign(&mut self, rhs: Worth) {
49        self.0 -= rhs.0;
50    }
51}
52
53impl ops::Mul<f64> for Worth {
54    type Output = Self;
55    fn mul(self, rhs: f64) -> Self {
56        Worth(self.0 * rhs)
57    }
58}
59
60impl ops::MulAssign<f64> for Worth {
61    fn mul_assign(&mut self, rhs: f64) {
62        self.0 = self.0 * rhs;
63    }
64}
65
66impl ops::Div<f64> for Worth {
67    type Output = Self;
68    fn div(self, rhs: f64) -> Self {
69        Worth(self.0 / rhs)
70    }
71}
72
73impl ops::Div<Worth> for f64 {
74    type Output = Worth;
75    fn div(self, rhs: Worth) -> Worth {
76        Worth(self / rhs.0)
77    }
78}
79
80impl ops::Div<Worth> for Worth {
81    type Output = f64;
82    fn div(self, rhs: Worth) -> f64 {
83        self.0 / rhs.0
84    }
85}
86
87// for min, max
88// https://www.reddit.com/r/rust/comments/29kia3/no_ord_for_f32/
89// impl Ord for Worth {
90//     fn cmp(&self, rhs: &Self) -> Ordering {
91//         // handle infinity
92//         self.0.partial_cmp(&rhs.0).unwrap_or(Ordering::Equal)
93//     }
94// }
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99
100    #[test]
101    fn test_worth() {
102        assert_eq!(Worth(0.5).0, 0.5);
103    }
104
105    #[test]
106    fn test_json_to_worth() {
107        let w: Worth = serde_json::from_str(r#"1.0"#).unwrap();
108        assert_eq!(w, Worth(1.0));
109    }
110}