brk_structs/structs/
stored_f64.rs

1use std::{
2    cmp::Ordering,
3    f64,
4    iter::Sum,
5    ops::{Add, AddAssign, Div, Mul},
6};
7
8use allocative::Allocative;
9use derive_deref::Deref;
10use serde::Serialize;
11use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
12use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
13
14use crate::{Bitcoin, Dollars};
15
16#[derive(
17    Debug,
18    Deref,
19    Default,
20    Clone,
21    Copy,
22    FromBytes,
23    Immutable,
24    IntoBytes,
25    KnownLayout,
26    Serialize,
27    StoredCompressed,
28    Allocative,
29)]
30pub struct StoredF64(f64);
31
32impl StoredF64 {
33    pub const NAN: Self = Self(f64::NAN);
34}
35
36impl From<f64> for StoredF64 {
37    fn from(value: f64) -> Self {
38        Self(value)
39    }
40}
41
42impl From<f32> for StoredF64 {
43    fn from(value: f32) -> Self {
44        Self(value as f64)
45    }
46}
47
48impl From<usize> for StoredF64 {
49    fn from(value: usize) -> Self {
50        Self(value as f64)
51    }
52}
53
54impl CheckedSub<StoredF64> for StoredF64 {
55    fn checked_sub(self, rhs: Self) -> Option<Self> {
56        Some(Self(self.0 - rhs.0))
57    }
58}
59
60impl Mul<usize> for StoredF64 {
61    type Output = Self;
62    fn mul(self, rhs: usize) -> Self::Output {
63        Self(self.0 * rhs as f64)
64    }
65}
66
67impl Mul<StoredF64> for StoredF64 {
68    type Output = Self;
69    fn mul(self, rhs: Self) -> Self::Output {
70        Self(self.0 * rhs.0)
71    }
72}
73
74impl Mul<Dollars> for StoredF64 {
75    type Output = Self;
76    fn mul(self, rhs: Dollars) -> Self::Output {
77        Self(self.0 * *rhs)
78    }
79}
80
81impl Div<usize> for StoredF64 {
82    type Output = Self;
83    fn div(self, rhs: usize) -> Self::Output {
84        Self(self.0 / rhs as f64)
85    }
86}
87
88impl Div<StoredF64> for StoredF64 {
89    type Output = Self;
90    fn div(self, rhs: Self) -> Self::Output {
91        Self(self.0 / rhs.0)
92    }
93}
94
95impl Div<Dollars> for StoredF64 {
96    type Output = Self;
97    fn div(self, rhs: Dollars) -> Self::Output {
98        Self::from(self.0 / *rhs)
99    }
100}
101
102impl Add for StoredF64 {
103    type Output = Self;
104    fn add(self, rhs: Self) -> Self::Output {
105        Self(self.0 + rhs.0)
106    }
107}
108
109impl AddAssign for StoredF64 {
110    fn add_assign(&mut self, rhs: Self) {
111        *self = *self + rhs
112    }
113}
114
115impl From<StoredF64> for f64 {
116    fn from(value: StoredF64) -> Self {
117        value.0
118    }
119}
120
121impl From<StoredF64> for f32 {
122    fn from(value: StoredF64) -> Self {
123        value.0 as f32
124    }
125}
126
127impl From<Dollars> for StoredF64 {
128    fn from(value: Dollars) -> Self {
129        Self(f64::from(value))
130    }
131}
132
133impl CheckedSub<usize> for StoredF64 {
134    fn checked_sub(self, rhs: usize) -> Option<Self> {
135        Some(Self(self.0 - rhs as f64))
136    }
137}
138
139impl PartialEq for StoredF64 {
140    fn eq(&self, other: &Self) -> bool {
141        match (self.0.is_nan(), other.0.is_nan()) {
142            (true, true) => true,
143            (true, false) => false,
144            (false, true) => false,
145            (false, false) => self.0 == other.0,
146        }
147    }
148}
149
150impl Eq for StoredF64 {}
151
152#[allow(clippy::derive_ord_xor_partial_ord)]
153impl PartialOrd for StoredF64 {
154    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
155        Some(self.cmp(other))
156    }
157}
158
159#[allow(clippy::derive_ord_xor_partial_ord)]
160impl Ord for StoredF64 {
161    fn cmp(&self, other: &Self) -> Ordering {
162        match (self.0.is_nan(), other.0.is_nan()) {
163            (true, true) => Ordering::Equal,
164            (true, false) => Ordering::Less,
165            (false, true) => Ordering::Greater,
166            (false, false) => self.0.partial_cmp(&other.0).unwrap(),
167        }
168    }
169}
170
171impl From<Bitcoin> for StoredF64 {
172    fn from(value: Bitcoin) -> Self {
173        Self(f64::from(value))
174    }
175}
176
177impl PrintableIndex for StoredF64 {
178    fn to_string() -> &'static str {
179        "f64"
180    }
181
182    fn to_possible_strings() -> &'static [&'static str] {
183        &["f64"]
184    }
185}
186
187impl Sum for StoredF64 {
188    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
189        Self(iter.map(|v| v.0).sum::<f64>())
190    }
191}
192
193impl Div<Bitcoin> for StoredF64 {
194    type Output = Self;
195    fn div(self, rhs: Bitcoin) -> Self::Output {
196        Self(self.0 / f64::from(rhs))
197    }
198}
199
200impl std::fmt::Display for StoredF64 {
201    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
202        let mut buf = ryu::Buffer::new();
203        let str = buf.format(self.0);
204        f.write_str(str)
205    }
206}