cosmwasm_common_library/
biginteger.rs1use crate::bigdecimal::BigDecimal;
2use core::fmt::{Display, Formatter};
3use core::str::FromStr;
4use std::iter::Sum;
5use cosmwasm_schema::cw_serde;
6use cosmwasm_std::{StdError, StdResult, Uint128, Uint256};
7use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
8
9#[cw_serde]
10#[derive(Copy, Default, Ord, PartialOrd, Eq)]
11pub struct BigInteger(pub Uint256);
12
13impl BigInteger {
14
15 pub const MAX: Self = Self(Uint256::MAX);
16 pub const MIN: Self = Self(Uint256::MIN);
17
18 pub const fn new(value: u128) -> Self {
19 Self(Uint256::from_u128(value))
20 }
21
22 pub fn scale_down(&self, decimals: u32) -> BigDecimal {
23 BigDecimal::from(*self, decimals)
24 }
25
26 pub fn scale_up(&self, decimals: u32) -> Self {
27 Self(self.0 * Uint256::from(10u64).pow(decimals))
28 }
29
30 pub fn to_uint128(&self) -> StdResult<Uint128> {
31 Ok(Uint128::try_from(self.0)?)
32 }
33
34 pub fn to_uint256(&self) -> Uint256 {
35 self.0
36 }
37
38 pub fn create_with_scale(value: u128, decimals: u32) -> Self {
39 Self::from(value).scale_up(decimals)
40 }
41
42 pub fn is_zero(&self) -> bool {
43 self.0.is_zero()
44 }
45
46 pub fn zero() -> Self {
47 Self(Uint256::zero())
48 }
49
50 pub fn one() -> Self {
51 Self(Uint256::one())
52 }
53
54 pub fn saturating_sub(&self, rhs: Self) -> Self {
55 Self(self.0.saturating_sub(rhs.0))
56 }
57
58 pub fn checked_sub(&self, rhs: Self) -> StdResult<Self> {
59 Ok(Self(self.0.checked_sub(rhs.0)?))
60 }
61
62 pub fn pow(&self, exp: u32) -> Self {
63 Self(self.0.pow(exp))
64 }
65
66 pub fn from_be_bytes(bytes: [u8; 32]) -> Self {
67 Self(Uint256::from_be_bytes(bytes))
68 }
69
70 pub fn from_le_bytes(bytes: [u8; 32]) -> Self {
71 Self(Uint256::from_le_bytes(bytes))
72 }
73
74 pub fn to_be_bytes(&self) -> [u8; 32] {
75 self.0.to_be_bytes()
76 }
77
78 pub fn to_le_bytes(&self) -> [u8; 32] {
79 self.0.to_le_bytes()
80 }
81}
82
83impl From<BigInteger> for String {
84 fn from(value: BigInteger) -> Self {
85 Self::from(value.0)
86 }
87}
88
89impl FromStr for BigInteger {
90 type Err = StdError;
91
92 fn from_str(s: &str) -> Result<Self, Self::Err> {
93 Ok(BigInteger(Uint256::from_str(s)?))
94 }
95}
96
97impl From<BigDecimal> for BigInteger {
98 fn from(value: BigDecimal) -> Self {
99 Self(value.0.to_uint_floor())
100 }
101}
102
103impl From<u128> for BigInteger {
104 fn from(value: u128) -> Self {
105 Self(Uint256::from_u128(value))
106 }
107}
108
109impl From<Uint128> for BigInteger {
110 fn from(value: Uint128) -> Self {
111 Self::from(value.u128())
112 }
113}
114
115impl From<BigInteger> for Uint256 {
116 fn from(value: BigInteger) -> Self {
117 value.0
118 }
119}
120
121impl From<u64> for BigInteger {
122 fn from(value: u64) -> Self {
123 Self(Uint256::from(value))
124 }
125}
126
127impl From<u32> for BigInteger {
128 fn from(value: u32) -> Self {
129 Self(Uint256::from(value))
130 }
131}
132
133impl From<u16> for BigInteger {
134 fn from(value: u16) -> Self {
135 Self(Uint256::from(value))
136 }
137}
138
139impl From<u8> for BigInteger {
140 fn from(value: u8) -> Self {
141 Self(Uint256::from(value))
142 }
143}
144
145impl Sub<BigInteger> for BigInteger {
146 type Output = BigInteger;
147
148 fn sub(self, rhs: BigInteger) -> Self::Output {
149 Self(self.0 - rhs.0)
150 }
151}
152
153impl Add<BigInteger> for BigInteger {
154 type Output = BigInteger;
155
156 fn add(self, rhs: BigInteger) -> Self::Output {
157 Self(self.0 + rhs.0)
158 }
159}
160
161impl Div<BigInteger> for BigInteger {
162 type Output = BigInteger;
163
164 fn div(self, rhs: BigInteger) -> Self::Output {
165 Self(self.0 / rhs.0)
166 }
167}
168
169impl Div<BigDecimal> for BigInteger {
170 type Output = BigDecimal;
171
172 #[allow(clippy::suspicious_arithmetic_impl)]
173 fn div(self, rhs: BigDecimal) -> Self::Output {
174 BigDecimal::from(self, 0) / rhs
175 }
176}
177
178impl Mul<BigInteger> for BigInteger {
179 type Output = BigInteger;
180
181 fn mul(self, rhs: BigInteger) -> Self::Output {
182 Self(self.0 * rhs.0)
183 }
184}
185
186impl Mul<BigDecimal> for BigInteger {
187 type Output = BigDecimal;
188
189 fn mul(self, rhs: BigDecimal) -> Self::Output {
190 rhs * self
191 }
192}
193
194impl AddAssign for BigInteger {
195 fn add_assign(&mut self, rhs: Self) {
196 self.0 += rhs.0;
197 }
198}
199
200impl SubAssign for BigInteger {
201 fn sub_assign(&mut self, rhs: Self) {
202 self.0 -= rhs.0;
203 }
204}
205
206impl MulAssign for BigInteger {
207 fn mul_assign(&mut self, rhs: Self) {
208 self.0 *= rhs.0;
209 }
210}
211
212impl DivAssign for BigInteger {
213 fn div_assign(&mut self, rhs: Self) {
214 self.0 /= rhs.0;
215 }
216}
217
218impl Display for BigInteger {
219 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
220 self.0.fmt(f)
221 }
222}
223
224impl Sum for BigInteger {
225 fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
226 iter.fold(Self::zero(), Add::add)
227 }
228}
229
230impl <'a> Sum<&'a BigInteger> for BigInteger {
231 fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
232 iter.fold(Self::zero(), |a, b| a + *b)
233 }
234}
235
236#[cfg(test)]
237mod tests {
238 use crate::bigdecimal::BigDecimal;
239 use crate::biginteger::BigInteger;
240 use cosmwasm_std::{Decimal256, Uint256};
241
242 #[test]
243 fn test_scale_down() {
244 let bigint = BigInteger(Uint256::from(1000000u64));
245 let bigdecimal = bigint.scale_down(6);
246 assert_eq!(bigdecimal, BigDecimal(Decimal256::one()));
247 }
248
249 #[test]
250 fn test_div() {
251 let d = BigDecimal::from(BigInteger::from(100000000000000000000u128), 0);
252 let i = BigInteger::from(100000000000000000000u128);
253 assert_eq!(i / d, BigDecimal::one());
254 }
255
256 #[test]
257 fn test_sum() {
258 let vector: Vec<BigInteger> = vec![BigInteger::from(1u64), BigInteger::from(2u64), BigInteger::from(3u64)];
259 assert_eq!(vector.clone().into_iter().sum::<BigInteger>(), BigInteger::from(6u64));
260 assert_eq!(vector.iter().sum::<BigInteger>(), BigInteger::from(6u64));
261 }
262
263 #[test]
264 fn test_bytes() {
265 let i = BigInteger(Uint256::from(1000000u64));
266
267 assert_eq!(BigInteger::from_be_bytes(i.to_be_bytes()), i);
268 }
269}