1pub use super::Int256;
2use bnum::types::U256;
3use bnum::BUint;
4use num_integer::Roots;
5use num_traits::{
6 Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, FromPrimitive, Num, One, Pow,
7 ToPrimitive, Zero,
8};
9use serde::ser::Serialize;
10use serde::{Deserialize, Deserializer, Serializer};
11use std::default::Default;
12use std::fmt;
13use std::num::IntErrorKind;
14use std::ops::{
15 Add, AddAssign, Deref, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr,
16 ShrAssign, Sub, SubAssign,
17};
18use std::str::FromStr;
19
20#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
21pub struct Uint256(pub U256);
22
23impl Uint256 {
24 pub fn from_le_bytes(slice: &[u8]) -> Uint256 {
25 let end = if slice.len() <= 32 { slice.len() } else { 32 };
28 Uint256(BUint::from_le_slice(&slice[0..end]).unwrap())
29 }
30 pub fn from_be_bytes(slice: &[u8]) -> Uint256 {
31 let end = if slice.len() <= 32 { slice.len() } else { 32 };
34 Uint256(BUint::from_be_slice(&slice[0..end]).unwrap())
35 }
36 pub fn to_be_bytes(&self) -> [u8; 32] {
37 let mut res = self.to_le_bytes();
38 res.reverse();
39 res
40 }
41 pub fn to_le_bytes(&self) -> [u8; 32] {
42 let mut res: [u8; 32] = [0; 32];
43 for i in 0usize..256 {
46 let byte_index = i / 8;
48 let bit_index = i % 8;
49 let bit = self.0.bit(i as u32);
51 if bit {
53 let scratch_bit = 1u8 << bit_index;
54 res[byte_index] |= scratch_bit
55 }
56 }
57 res
58 }
59 pub fn to_int256(&self) -> Option<Int256> {
61 if *self <= Int256::max_value().to_uint256().unwrap() {
62 Some(Int256::from_str_radix(&self.to_str_radix(10), 10).unwrap())
63 } else {
64 None
65 }
66 }
67
68 pub fn sqrt(&self) -> Uint256 {
70 Self(self.0.sqrt())
71 }
72}
73
74impl Num for Uint256 {
75 type FromStrRadixErr = crate::error::ParseError;
76
77 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
78 let res = Uint256(U256::from_str_radix(str, radix)?);
79 if res > Uint256::max_value() {
80 return Err(Self::FromStrRadixErr::new(IntErrorKind::PosOverflow));
81 } else if res < Uint256::min_value() {
82 return Err(Self::FromStrRadixErr::new(IntErrorKind::NegOverflow));
83 }
84 Ok(res)
85 }
86}
87
88impl One for Uint256 {
89 fn one() -> Self {
90 Uint256(U256::ONE)
91 }
92}
93
94impl Zero for Uint256 {
95 fn zero() -> Self {
96 Uint256(U256::ZERO)
97 }
98
99 fn is_zero(&self) -> bool {
100 *self == Uint256::zero()
101 }
102}
103
104impl FromPrimitive for Uint256 {
105 fn from_i64(n: i64) -> Option<Self> {
106 let val: Result<U256, _> = n.try_into();
107 match val {
108 Ok(v) => Some(Uint256(v)),
109 Err(_) => None,
110 }
111 }
112
113 fn from_u64(n: u64) -> Option<Self> {
114 let val: U256 = n.into();
115 Some(Uint256(val))
116 }
117
118 fn from_i128(n: i128) -> Option<Self> {
119 let val: Result<U256, _> = n.try_into();
120 match val {
121 Ok(v) => Some(Uint256(v)),
122 Err(_) => None,
123 }
124 }
125
126 fn from_u128(n: u128) -> Option<Self> {
127 let val: U256 = n.into();
128 Some(Uint256(val))
129 }
130}
131
132impl ToPrimitive for Uint256 {
133 fn to_i64(&self) -> Option<i64> {
134 match self.0.try_into() {
135 Ok(v) => Some(v),
136 Err(_) => None,
137 }
138 }
139
140 fn to_u64(&self) -> Option<u64> {
141 match self.0.try_into() {
142 Ok(v) => Some(v),
143 Err(_) => None,
144 }
145 }
146
147 fn to_i128(&self) -> Option<i128> {
148 match self.0.try_into() {
149 Ok(v) => Some(v),
150 Err(_) => None,
151 }
152 }
153
154 fn to_u128(&self) -> Option<u128> {
155 match self.0.try_into() {
156 Ok(v) => Some(v),
157 Err(_) => None,
158 }
159 }
160}
161
162impl Bounded for Uint256 {
163 fn min_value() -> Self {
164 Uint256::zero()
166 }
167 fn max_value() -> Self {
168 let max_value: Uint256 =
169 "115792089237316195423570985008687907853269984665640564039457584007913129639935"
170 .parse()
171 .unwrap();
172 max_value
173 }
174}
175
176impl FromStr for Uint256 {
177 type Err = crate::error::ParseError;
178 fn from_str(s: &str) -> Result<Self, Self::Err> {
179 if let Some(val) = s.strip_prefix("0x") {
180 Ok(U256::from_str_radix(val, 16).map(Uint256)?)
181 } else {
182 Ok(U256::from_str_radix(s, 10).map(Uint256)?)
183 }
184 }
185}
186
187impl TryFrom<&str> for Uint256 {
188 type Error = crate::error::ParseError;
189
190 fn try_from(value: &str) -> Result<Self, Self::Error> {
191 value.parse()
192 }
193}
194
195impl fmt::Display for Uint256 {
196 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
197 write!(f, "{}", &self.0.to_str_radix(10))
198 }
199}
200
201impl fmt::Debug for Uint256 {
202 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203 write!(f, "Uint256({})", &self.0.to_str_radix(10))
204 }
205}
206
207impl fmt::LowerHex for Uint256 {
208 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
209 let hex_str = &self.0.to_str_radix(16);
210 let mut width = hex_str.len();
211 if f.alternate() {
212 write!(f, "0x")?;
213 width += 2;
214 }
215 if let Some(desired_width) = f.width() {
216 if desired_width > width {
217 let pad = String::from_utf8(vec![b'0'; desired_width - width]).unwrap();
218 write!(f, "{}", &pad)?;
219 }
220 }
221 write!(f, "{hex_str}")
222 }
223}
224
225impl fmt::UpperHex for Uint256 {
226 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
227 let hex_str = &self.0.to_str_radix(16).to_uppercase();
228 let mut width = hex_str.len();
229 if f.alternate() {
230 write!(f, "0x")?;
231 width += 2;
232 }
233 if let Some(desired_width) = f.width() {
234 if desired_width > width {
235 let pad = String::from_utf8(vec![b'0'; desired_width - width]).unwrap();
236 write!(f, "{}", &pad)?;
237 }
238 }
239 write!(f, "{hex_str}")
240 }
241}
242
243impl Deref for Uint256 {
244 type Target = U256;
245
246 fn deref(&self) -> &U256 {
247 &self.0
248 }
249}
250
251impl Serialize for Uint256 {
252 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
253 where
254 S: Serializer,
255 {
256 serializer.serialize_str(&self.0.to_str_radix(10))
257 }
258}
259
260impl<'de> Deserialize<'de> for Uint256 {
261 fn deserialize<D>(deserializer: D) -> Result<Uint256, D::Error>
262 where
263 D: Deserializer<'de>,
264 {
265 let s = String::deserialize(deserializer)?;
266
267 let (radix, data) = if let Some(val) = s.strip_prefix("0x") {
271 (16, val)
272 } else {
273 (10, s.as_str())
274 };
275
276 U256::from_str_radix(data, radix)
278 .map(Uint256)
279 .map_err(serde::de::Error::custom)
280 }
281}
282
283impl From<[u8; 32]> for Uint256 {
284 fn from(n: [u8; 32]) -> Uint256 {
285 Uint256::from_be_bytes(&n)
286 }
287}
288
289impl<'a> From<&'a [u8]> for Uint256 {
290 fn from(n: &'a [u8]) -> Uint256 {
291 Uint256::from_be_bytes(n)
292 }
293}
294
295impl TryFrom<Int256> for Uint256 {
296 type Error = ();
297
298 fn try_from(value: Int256) -> Result<Self, Self::Error> {
299 match value.to_uint256() {
300 Some(v) => Ok(v),
301 None => Err(()),
302 }
303 }
304}
305
306#[allow(clippy::from_over_into)]
307impl Into<[u8; 32]> for Uint256 {
308 fn into(self) -> [u8; 32] {
309 self.to_be_bytes()
310 }
311}
312
313impl Pow<u32> for Uint256 {
314 type Output = Self;
315
316 fn pow(self, p: u32) -> Self::Output {
317 Uint256(self.0.pow(p))
318 }
319}
320
321macro_rules! uint_impl_from_uint {
322 ($T:ty) => {
323 impl From<$T> for Uint256 {
324 #[inline]
325 fn from(n: $T) -> Self {
326 Uint256(U256::from(n))
327 }
328 }
329 };
330}
331
332uint_impl_from_uint!(u8);
334uint_impl_from_uint!(u16);
335uint_impl_from_uint!(u32);
336uint_impl_from_uint!(u64);
337uint_impl_from_uint!(u128);
338uint_impl_from_uint!(usize);
339
340macro_rules! forward_op {
342 (impl $trait_: ident for $type_: ident { fn $method: ident }) => {
343 impl $trait_<$type_> for $type_ {
344 type Output = $type_;
345
346 fn $method(self, $type_(b): $type_) -> $type_ {
347 let $type_(a) = self;
348 let res = a.$method(&b);
349 Uint256(res)
350 }
351 }
352 };
353}
354
355macro_rules! forward_checked_op {
357 (impl $trait_: ident for $type_: ident { fn $method: ident }) => {
358 impl $trait_ for $type_ {
359 fn $method(&self, $type_(b): &$type_) -> Option<$type_> {
360 let $type_(a) = self;
361 let value = a.$method(b);
362 match value {
363 Some(value) => Some(Uint256(value)),
364 None => None,
365 }
366 }
367 }
368 };
369}
370
371macro_rules! forward_assign_op {
373 (impl $trait_: ident for $type_: ident { fn $method: ident }) => {
374 impl $trait_ for $type_ {
375 fn $method(&mut self, $type_(b): $type_) {
376 let a = &mut self.0;
377 a.$method(b);
378 }
379 }
380 };
381}
382
383forward_op! { impl Add for Uint256 { fn add } }
384forward_checked_op! { impl CheckedAdd for Uint256 { fn checked_add } }
385forward_assign_op! { impl AddAssign for Uint256 { fn add_assign } }
386
387forward_op! { impl Sub for Uint256 { fn sub } }
388forward_checked_op! { impl CheckedSub for Uint256 { fn checked_sub } }
389forward_assign_op! { impl SubAssign for Uint256 { fn sub_assign } }
390
391forward_op! { impl Mul for Uint256 { fn mul } }
392forward_checked_op! { impl CheckedMul for Uint256 { fn checked_mul } }
393forward_assign_op! { impl MulAssign for Uint256 { fn mul_assign } }
394
395forward_op! { impl Div for Uint256 { fn div } }
396forward_checked_op! { impl CheckedDiv for Uint256 { fn checked_div } }
397forward_assign_op! { impl DivAssign for Uint256 { fn div_assign } }
398
399forward_op! { impl Shl for Uint256 { fn shl } }
400forward_assign_op! { impl ShlAssign for Uint256 { fn shl_assign } }
401
402forward_op! { impl Shr for Uint256 { fn shr } }
403forward_assign_op! { impl ShrAssign for Uint256 { fn shr_assign } }
404
405forward_op! { impl Rem for Uint256 { fn rem } }
406forward_assign_op! { impl RemAssign for Uint256 { fn rem_assign } }
407
408#[test]
409fn create_from_32_bytes() {
410 let lhs: [u8; 32] = [
411 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
412 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
413 0x42, 0x42,
414 ];
415 let lhs: Uint256 = lhs.into();
416 assert_eq!(
417 lhs,
418 "0x4242424242424242424242424242424242424242424242424242424242424242"
419 .parse()
420 .unwrap()
421 );
422}
423
424#[test]
425fn to_hex() {
426 let lhs: Uint256 = "0xbabababababababababababababababababababababababababababababababa"
427 .parse()
428 .unwrap();
429 assert_eq!(
430 format!("{lhs:#x}"),
431 "0xbabababababababababababababababababababababababababababababababa"
432 );
433 assert_eq!(
434 format!("{lhs:x}"),
435 "babababababababababababababababababababababababababababababababa"
436 );
437 assert_eq!(
438 format!("{lhs:X}"),
439 "BABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA"
440 );
441 assert_eq!(
442 format!("{lhs:#X}"),
443 "0xBABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA"
444 );
445}
446
447#[test]
448fn to_hex_with_padding() {
449 let lhs: Uint256 = "0xbababababababababababababababababababababababababababa"
450 .parse()
451 .unwrap();
452 assert_eq!(
453 format!("{lhs:#066x}"),
454 "0x0000000000bababababababababababababababababababababababababababa"
455 );
456 assert_eq!(
457 format!("{lhs:064x}"),
458 "0000000000bababababababababababababababababababababababababababa"
459 );
460 assert_eq!(
461 format!("{lhs:064X}"),
462 "0000000000BABABABABABABABABABABABABABABABABABABABABABABABABABABA"
463 );
464 assert_eq!(
465 format!("{lhs:#066X}"),
466 "0x0000000000BABABABABABABABABABABABABABABABABABABABABABABABABABABA"
467 );
468}
469
470#[test]
471fn into_array() {
472 let val = Uint256::from(1024u16);
473 let data: [u8; 32] = val.into();
474 assert_eq!(
475 data,
476 [
477 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
478 0, 4, 0
479 ]
480 );
481}
482
483#[test]
484fn check_display() {
485 let val = Uint256::max_value();
486 assert_eq!(
487 format!("{val}"),
488 "115792089237316195423570985008687907853269984665640564039457584007913129639935"
489 );
490 assert_eq!(
491 val.to_string(),
492 "115792089237316195423570985008687907853269984665640564039457584007913129639935"
493 );
494}
495
496#[test]
497fn check_from_str_radix_overflow() {
498 let super_huge =
499 "115792089237316195423570985008687907853369984665640564039457584007913129639935";
500 let val = Uint256::from_str_radix(super_huge, 10);
501 assert!(val.is_err())
502}
503
504#[test]
506fn test_to_primitive_64() {
507 let u32_max: u64 = u32::MAX.into();
508 use num_traits::ToPrimitive;
509 let mut i = 0u64;
510 while i < 100_000 {
511 let i_uint256: Uint256 = i.into();
512 assert_eq!(i, (i_uint256).to_u64().unwrap());
513 assert_eq!(i as i64, (i_uint256).to_i64().unwrap());
514 i += 1
515 }
516
517 let mut i: u64 = u32_max - 100;
518 let end = i + 100_000;
519 while i < end {
520 let i_uint256: Uint256 = i.into();
521 assert_eq!(i, i_uint256.to_u64().unwrap());
522 if i < u32_max {
523 assert_eq!(i as i64, i_uint256.to_i64().unwrap());
524 }
525 i += 1
526 }
527}
528
529#[test]
532fn test_to_primitive_128() {
533 let u64_max: u128 = u64::MAX.into();
534 use num_traits::ToPrimitive;
535 let mut i = 0u128;
536 while i < 100_000 {
537 let i_uint256: Uint256 = i.into();
538 assert_eq!(i, i_uint256.to_u128().unwrap());
539 assert_eq!(i as i128, i_uint256.to_i128().unwrap());
540 i += 1
541 }
542 let mut i: u128 = u64_max - 100;
543 let end = i + 100_000;
544 while i < end {
545 let i_uint256: Uint256 = i.into();
546 assert_eq!(i, i_uint256.to_u128().unwrap());
547 if i < u64_max {
548 assert_eq!(i as i128, i_uint256.to_i128().unwrap());
549 }
550 i += 1
551 }
552}
553
554#[test]
555fn test_sqrt() {
556 use rand::prelude::*;
557
558 for _ in 1..100000 {
559 let r: u128 = random();
560 let n = Uint256::from(r);
561 let sqrt = (n.mul(n)).sqrt();
562 assert!(sqrt == n);
563 }
564}