ab_core_primitives/
balance.rs1use ab_io_type::metadata::IoTypeMetadataKind;
4use ab_io_type::trivial_type::TrivialType;
5use core::cmp::Ordering;
6use core::mem::MaybeUninit;
7use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
8use core::{fmt, ptr};
9
10#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
14#[repr(C)]
15pub struct Balance(u64, u64);
16
17unsafe impl TrivialType for Balance {
19 const METADATA: &[u8] = &[IoTypeMetadataKind::Balance as u8];
20}
21
22const _: () = {
24 let (type_details, _metadata) = IoTypeMetadataKind::type_details(Balance::METADATA)
25 .expect("Statically correct metadata; qed");
26 assert!(size_of::<Balance>() == type_details.recommended_capacity as usize);
27 assert!(align_of::<Balance>() == type_details.alignment.get() as usize);
28};
29
30impl fmt::Debug for Balance {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 f.debug_tuple("Balance").field(&self.as_u128()).finish()
33 }
34}
35
36impl fmt::Display for Balance {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 self.as_u128().fmt(f)
39 }
40}
41
42impl Ord for Balance {
43 #[inline(always)]
44 fn cmp(&self, other: &Balance) -> Ordering {
45 self.as_u128().cmp(&other.as_u128())
46 }
47}
48
49impl PartialOrd for Balance {
50 #[inline(always)]
51 fn partial_cmp(&self, other: &Balance) -> Option<Ordering> {
52 Some(self.cmp(other))
53 }
54}
55
56impl Add for Balance {
57 type Output = Balance;
58
59 #[inline(always)]
60 #[track_caller]
61 fn add(self, rhs: Balance) -> Balance {
62 Self::new(self.as_u128().add(rhs.as_u128()))
63 }
64}
65
66impl AddAssign for Balance {
67 #[inline(always)]
68 #[track_caller]
69 fn add_assign(&mut self, rhs: Balance) {
70 *self = *self + rhs;
71 }
72}
73
74impl Sub for Balance {
75 type Output = Balance;
76
77 #[inline(always)]
78 #[track_caller]
79 fn sub(self, rhs: Balance) -> Balance {
80 Self::new(self.as_u128().sub(rhs.as_u128()))
81 }
82}
83
84impl SubAssign for Balance {
85 #[inline(always)]
86 #[track_caller]
87 fn sub_assign(&mut self, rhs: Balance) {
88 *self = *self - rhs;
89 }
90}
91
92impl<Rhs> Mul<Rhs> for Balance
93where
94 u128: Mul<Rhs, Output = u128>,
95{
96 type Output = Balance;
97
98 #[inline(always)]
99 #[track_caller]
100 fn mul(self, rhs: Rhs) -> Balance {
101 Self::new(<u128 as Mul<Rhs>>::mul(self.as_u128(), rhs))
102 }
103}
104
105impl<Rhs> MulAssign<Rhs> for Balance
106where
107 u128: Mul<Rhs, Output = u128>,
108{
109 #[inline(always)]
110 #[track_caller]
111 fn mul_assign(&mut self, rhs: Rhs) {
112 *self = *self * rhs;
113 }
114}
115
116impl<Rhs> Div<Rhs> for Balance
117where
118 u128: Div<Rhs, Output = u128>,
119{
120 type Output = Balance;
121
122 #[inline(always)]
123 #[track_caller]
124 fn div(self, rhs: Rhs) -> Balance {
125 Self::new(<u128 as Div<Rhs>>::div(self.as_u128(), rhs))
126 }
127}
128
129impl<Rhs> DivAssign<Rhs> for Balance
130where
131 u128: Div<Rhs, Output = u128>,
132{
133 #[inline(always)]
134 #[track_caller]
135 fn div_assign(&mut self, rhs: Rhs) {
136 *self = *self / rhs;
137 }
138}
139
140impl From<u128> for Balance {
141 #[inline(always)]
142 fn from(value: u128) -> Self {
143 Self::new(value)
144 }
145}
146
147impl From<Balance> for u128 {
148 #[inline(always)]
149 fn from(value: Balance) -> Self {
150 value.as_u128()
151 }
152}
153
154impl Balance {
155 pub const MIN: Self = Self::new(0);
157 pub const MAX: Self = Self::new(u128::MAX);
159
160 #[inline(always)]
162 pub const fn new(n: u128) -> Self {
163 let mut result = MaybeUninit::<Self>::uninit();
164 unsafe {
166 result.as_mut_ptr().cast::<u128>().write_unaligned(n);
167 result.assume_init()
168 }
169 }
170
171 #[inline(always)]
173 pub const fn as_u128(self) -> u128 {
174 unsafe { ptr::from_ref(&self).cast::<u128>().read_unaligned() }
176 }
177}