brk_structs/structs/
bitcoin.rs1use 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 }
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}