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