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(&u128::from(self)).finish()
33 }
34}
35
36impl fmt::Display for Balance {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 u128::from(self).fmt(f)
39 }
40}
41
42impl Ord for Balance {
43 #[inline(always)]
44 fn cmp(&self, other: &Balance) -> Ordering {
45 u128::from(self).cmp(&u128::from(other))
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::from(u128::from(self).add(u128::from(rhs)))
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::from(u128::from(self).sub(u128::from(rhs)))
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::from(<u128 as Mul<Rhs>>::mul(u128::from(self), 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::from(<u128 as Div<Rhs>>::div(u128::from(self), 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 const From<u128> for Balance {
141 #[inline(always)]
142 fn from(value: u128) -> Self {
143 let mut result = MaybeUninit::<Self>::uninit();
144 unsafe {
146 result.as_mut_ptr().cast::<u128>().write_unaligned(value);
147 result.assume_init()
148 }
149 }
150}
151
152impl const From<&Balance> for u128 {
153 #[inline(always)]
154 fn from(value: &Balance) -> Self {
155 unsafe { ptr::from_ref(value).cast::<u128>().read_unaligned() }
157 }
158}
159
160impl const From<Balance> for u128 {
161 #[inline(always)]
162 fn from(value: Balance) -> Self {
163 Self::from(&value)
164 }
165}
166
167impl Balance {
168 pub const MIN: Self = Self::from(0);
170 pub const MAX: Self = Self::from(u128::MAX);
172}