brk_structs/structs/
bitcoin.rs

1use std::{
2    cmp::Ordering,
3    ops::{Add, AddAssign, Div, Mul},
4};
5
6use allocative::Allocative;
7use serde::Serialize;
8use vecdb::{CheckedSub, StoredCompressed};
9use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
10
11use super::{Sats, StoredF64};
12
13#[derive(
14    Debug,
15    Default,
16    Clone,
17    Copy,
18    FromBytes,
19    Immutable,
20    IntoBytes,
21    KnownLayout,
22    Serialize,
23    StoredCompressed,
24    Allocative,
25)]
26pub struct Bitcoin(f64);
27
28impl Add for Bitcoin {
29    type Output = Self;
30    fn add(self, rhs: Self) -> Self::Output {
31        Self::from(Sats::from(self) + Sats::from(rhs))
32    }
33}
34
35impl AddAssign for Bitcoin {
36    fn add_assign(&mut self, rhs: Self) {
37        *self = *self + rhs
38    }
39}
40
41impl Mul for Bitcoin {
42    type Output = Self;
43    fn mul(self, rhs: Self) -> Self::Output {
44        Self::from(Sats::from(self) * Sats::from(rhs))
45    }
46}
47
48impl Mul<usize> for Bitcoin {
49    type Output = Self;
50    fn mul(self, rhs: usize) -> Self::Output {
51        Self::from(Sats::from(self) * rhs)
52    }
53}
54
55impl Div<Bitcoin> for Bitcoin {
56    type Output = StoredF64;
57    fn div(self, rhs: Bitcoin) -> Self::Output {
58        StoredF64::from(self.0 / rhs.0)
59        // Self::from(Sats::from(self) / Sats::from(rhs))
60    }
61}
62
63impl Div<usize> for Bitcoin {
64    type Output = Self;
65    fn div(self, rhs: usize) -> Self::Output {
66        Self::from(Sats::from(self) / rhs)
67    }
68}
69
70impl From<Sats> for Bitcoin {
71    fn from(value: Sats) -> Self {
72        Self(f64::from(value) / (f64::from(Sats::ONE_BTC)))
73    }
74}
75
76impl From<f64> for Bitcoin {
77    fn from(value: f64) -> Self {
78        Self(value)
79    }
80}
81
82impl From<StoredF64> for Bitcoin {
83    fn from(value: StoredF64) -> Self {
84        Self(*value)
85    }
86}
87
88impl From<Bitcoin> for f64 {
89    fn from(value: Bitcoin) -> Self {
90        value.0
91    }
92}
93
94impl From<usize> for Bitcoin {
95    fn from(value: usize) -> Self {
96        Self(value as f64)
97    }
98}
99
100impl PartialEq for Bitcoin {
101    fn eq(&self, other: &Self) -> bool {
102        match (self.0.is_nan(), other.0.is_nan()) {
103            (true, true) => true,
104            (true, false) => false,
105            (false, true) => false,
106            (false, false) => self.0 == other.0,
107        }
108    }
109}
110
111impl Eq for Bitcoin {}
112
113#[allow(clippy::derive_ord_xor_partial_ord)]
114impl PartialOrd for Bitcoin {
115    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
116        Some(self.cmp(other))
117    }
118}
119
120#[allow(clippy::derive_ord_xor_partial_ord)]
121impl Ord for Bitcoin {
122    fn cmp(&self, other: &Self) -> Ordering {
123        match (self.0.is_nan(), other.0.is_nan()) {
124            (true, true) => Ordering::Equal,
125            (true, false) => Ordering::Less,
126            (false, true) => Ordering::Greater,
127            (false, false) => self.0.partial_cmp(&other.0).unwrap(),
128        }
129    }
130}
131
132impl CheckedSub<usize> for Bitcoin {
133    fn checked_sub(self, rhs: usize) -> Option<Self> {
134        Some(Self(self.0 - rhs as f64))
135    }
136}
137impl CheckedSub<Bitcoin> for Bitcoin {
138    fn checked_sub(self, rhs: Bitcoin) -> Option<Self> {
139        Some(Self(self.0 - rhs.0))
140    }
141}
142
143impl std::fmt::Display for Bitcoin {
144    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145        let mut buf = ryu::Buffer::new();
146        let str = buf.format(self.0);
147        f.write_str(str)
148    }
149}