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