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