1use std::fmt;
5use std::mem::size_of;
6use std::ops::{
7 Add,
8 AddAssign,
9 BitAnd,
10 BitAndAssign,
11 BitOr,
12 BitXor,
13 Div,
14 DivAssign,
15 Mul,
16 MulAssign,
17 Rem,
18 RemAssign,
19 Shl,
20 Shr,
21 Sub,
22 SubAssign,
23};
24
25use primitive_types::U256 as PrimitiveU256;
27use uint::FromStrRadixErr;
28
29const NUM_BITS_PER_BYTE: usize = 8;
30const U256_NUM_BITS: usize = 256;
31pub const U256_NUM_BYTES: usize = U256_NUM_BITS / NUM_BITS_PER_BYTE;
32
33#[derive(Debug)]
34pub struct U256FromStrError(FromStrRadixErr);
35
36#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
38pub enum U256CastErrorKind {
39 TooLargeForU8,
41
42 TooLargeForU16,
44
45 TooLargeForU32,
47
48 TooLargeForU64,
50
51 TooLargeForU128,
53}
54
55#[derive(Debug)]
56pub struct U256CastError {
57 kind: U256CastErrorKind,
58 val: U256,
59}
60
61impl U256CastError {
62 pub fn new<T: std::convert::Into<U256>>(val: T, kind: U256CastErrorKind) -> Self {
63 Self {
64 kind,
65 val: val.into(),
66 }
67 }
68}
69
70impl std::error::Error for U256CastError {}
71
72impl fmt::Display for U256CastError {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 let type_str = match self.kind {
75 U256CastErrorKind::TooLargeForU8 => "u8",
76 U256CastErrorKind::TooLargeForU16 => "u16",
77 U256CastErrorKind::TooLargeForU32 => "u32",
78 U256CastErrorKind::TooLargeForU64 => "u64",
79 U256CastErrorKind::TooLargeForU128 => "u128",
80 };
81 let err_str = format!("Cast failed. {} too large for {}.", self.val, type_str);
82 write!(f, "{err_str}")
83 }
84}
85
86impl std::error::Error for U256FromStrError {
87 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
88 self.0.source()
89 }
90}
91
92impl fmt::Display for U256FromStrError {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 write!(f, "{}", self.0)
95 }
96}
97
98#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy, PartialOrd, Ord, Default)]
99pub struct U256(PrimitiveU256);
100
101impl fmt::Display for U256 {
102 fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
103 self.0.fmt(f)
104 }
105}
106
107impl fmt::UpperHex for U256 {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 fmt::UpperHex::fmt(&self.0, f)
110 }
111}
112
113impl fmt::LowerHex for U256 {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 fmt::LowerHex::fmt(&self.0, f)
116 }
117}
118
119impl std::str::FromStr for U256 {
120 type Err = U256FromStrError;
121
122 fn from_str(s: &str) -> Result<Self, Self::Err> {
123 Self::from_str_radix(s, 10)
124 }
125}
126
127#[cfg(feature = "serde")]
128impl<'de> serde::Deserialize<'de> for U256 {
129 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
130 where
131 D: serde::Deserializer<'de>,
132 {
133 Ok(Self::from_le_bytes(
134 &(<[u8; U256_NUM_BYTES]>::deserialize(deserializer)?),
135 ))
136 }
137}
138
139#[cfg(feature = "serde")]
140impl serde::Serialize for U256 {
141 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
142 where
143 S: serde::Serializer,
144 {
145 self.to_le_bytes().serialize(serializer)
146 }
147}
148
149impl Shl<u32> for U256 {
150 type Output = Self;
151
152 fn shl(self, rhs: u32) -> Self::Output {
153 let Self(lhs) = self;
154 Self(lhs << rhs)
155 }
156}
157
158impl Shl<u8> for U256 {
159 type Output = Self;
160
161 fn shl(self, rhs: u8) -> Self::Output {
162 let Self(lhs) = self;
163 Self(lhs << rhs)
164 }
165}
166
167impl Shr<u8> for U256 {
168 type Output = Self;
169
170 fn shr(self, rhs: u8) -> Self::Output {
171 let Self(lhs) = self;
172 Self(lhs >> rhs)
173 }
174}
175
176impl BitOr<Self> for U256 {
177 type Output = Self;
178
179 fn bitor(self, rhs: Self) -> Self::Output {
180 let Self(lhs) = self;
181 let Self(rhs) = rhs;
182 Self(lhs | rhs)
183 }
184}
185
186impl BitAnd<Self> for U256 {
187 type Output = Self;
188
189 fn bitand(self, rhs: Self) -> Self::Output {
190 let Self(lhs) = self;
191 let Self(rhs) = rhs;
192 Self(lhs & rhs)
193 }
194}
195
196impl BitXor<Self> for U256 {
197 type Output = Self;
198
199 fn bitxor(self, rhs: Self) -> Self::Output {
200 let Self(lhs) = self;
201 let Self(rhs) = rhs;
202 Self(lhs ^ rhs)
203 }
204}
205
206impl BitAndAssign<Self> for U256 {
207 fn bitand_assign(&mut self, rhs: Self) {
208 *self = *self & rhs;
209 }
210}
211
212impl Add<Self> for U256 {
214 type Output = Self;
215
216 fn add(self, rhs: Self) -> Self::Output {
217 self.wrapping_add(rhs)
218 }
219}
220
221impl AddAssign<Self> for U256 {
222 fn add_assign(&mut self, rhs: Self) {
223 *self = *self + rhs;
224 }
225}
226
227impl Sub<Self> for U256 {
229 type Output = Self;
230
231 fn sub(self, rhs: Self) -> Self::Output {
232 self.wrapping_sub(rhs)
233 }
234}
235
236impl SubAssign<Self> for U256 {
237 fn sub_assign(&mut self, rhs: Self) {
238 *self = *self - rhs;
239 }
240}
241
242impl Mul<Self> for U256 {
244 type Output = Self;
245
246 fn mul(self, rhs: Self) -> Self::Output {
247 self.wrapping_mul(rhs)
248 }
249}
250
251impl MulAssign<Self> for U256 {
252 fn mul_assign(&mut self, rhs: Self) {
253 *self = *self * rhs;
254 }
255}
256
257impl Div<Self> for U256 {
258 type Output = Self;
259
260 fn div(self, rhs: Self) -> Self::Output {
261 Self(self.0 / rhs.0)
262 }
263}
264
265impl DivAssign<Self> for U256 {
266 fn div_assign(&mut self, rhs: Self) {
267 *self = *self / rhs;
268 }
269}
270
271impl Rem<Self> for U256 {
272 type Output = Self;
273
274 fn rem(self, rhs: Self) -> Self::Output {
275 Self(self.0 % rhs.0)
276 }
277}
278
279impl RemAssign<Self> for U256 {
280 fn rem_assign(&mut self, rhs: Self) {
281 *self = Self(self.0 % rhs.0);
282 }
283}
284
285impl U256 {
286 pub const fn zero() -> Self {
288 Self(PrimitiveU256::zero())
289 }
290
291 pub const fn one() -> Self {
293 Self(PrimitiveU256::one())
294 }
295
296 pub const fn max_value() -> Self {
298 Self(PrimitiveU256::max_value())
299 }
300
301 pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, U256FromStrError> {
303 PrimitiveU256::from_str_radix(src.trim_start_matches('0'), radix)
304 .map(Self)
305 .map_err(U256FromStrError)
306 }
307
308 pub fn from_le_bytes(slice: &[u8; U256_NUM_BYTES]) -> Self {
310 Self(PrimitiveU256::from_little_endian(slice))
311 }
312
313 pub fn to_le_bytes(self) -> [u8; U256_NUM_BYTES] {
315 let mut bytes = [0u8; U256_NUM_BYTES];
316 self.0.to_little_endian(&mut bytes);
317 bytes
318 }
319
320 pub fn leading_zeros(&self) -> u32 {
322 self.0.leading_zeros()
323 }
324
325 pub const fn unchecked_as_u8(&self) -> u8 {
327 self.0.low_u128() as u8
328 }
329
330 pub const fn unchecked_as_u16(&self) -> u16 {
331 self.0.low_u128() as u16
332 }
333
334 pub const fn unchecked_as_u32(&self) -> u32 {
335 self.0.low_u128() as u32
336 }
337
338 pub const fn unchecked_as_u64(&self) -> u64 {
339 self.0.low_u128() as u64
340 }
341
342 pub const fn unchecked_as_u128(&self) -> u128 {
343 self.0.low_u128()
344 }
345
346 pub fn checked_add(self, rhs: Self) -> Option<Self> {
349 self.0.checked_add(rhs.0).map(Self)
350 }
351
352 pub fn checked_sub(self, rhs: Self) -> Option<Self> {
354 self.0.checked_sub(rhs.0).map(Self)
355 }
356
357 pub fn checked_mul(self, rhs: Self) -> Option<Self> {
359 self.0.checked_mul(rhs.0).map(Self)
360 }
361
362 pub fn checked_div(self, rhs: Self) -> Option<Self> {
364 self.0.checked_div(rhs.0).map(Self)
365 }
366
367 pub fn checked_rem(self, rhs: Self) -> Option<Self> {
369 self.0.checked_rem(rhs.0).map(Self)
370 }
371
372 pub fn checked_shl(self, rhs: u32) -> Option<Self> {
374 if rhs >= U256_NUM_BITS as u32 {
375 return None;
376 }
377 Some(Self(self.0.shl(rhs)))
378 }
379
380 pub fn checked_shr(self, rhs: u32) -> Option<Self> {
382 if rhs >= U256_NUM_BITS as u32 {
383 return None;
384 }
385 Some(Self(self.0.shr(rhs)))
386 }
387
388 pub fn down_cast_lossy<T: std::convert::TryFrom<u128>>(self) -> T {
391 let type_size = size_of::<T>();
393 let max_val: u128 = if type_size < 16 {
395 (1u128 << (NUM_BITS_PER_BYTE * type_size)) - 1u128
396 } else {
397 u128::MAX
398 };
399 #[expect(clippy::option_if_let_else)]
401 match T::try_from(self.0.low_u128() & max_val) {
402 Ok(w) => w,
403 Err(_) => panic!("Fatal! Downcast failed"),
404 }
405 }
406
407 pub fn wrapping_add(self, rhs: Self) -> Self {
410 Self(self.0.overflowing_add(rhs.0).0)
411 }
412
413 pub fn wrapping_sub(self, rhs: Self) -> Self {
416 Self(self.0.overflowing_sub(rhs.0).0)
417 }
418
419 pub fn wrapping_mul(self, rhs: Self) -> Self {
422 Self(self.0.overflowing_mul(rhs.0).0)
423 }
424
425 pub fn from_f64_lossy(value: f64) -> Self {
426 Self(PrimitiveU256::from_f64_lossy(value))
427 }
428
429 pub fn to_f64_lossy(self) -> f64 {
430 self.0.to_f64_lossy()
431 }
432}
433
434impl From<u8> for U256 {
435 fn from(n: u8) -> Self {
436 Self(PrimitiveU256::from(n))
437 }
438}
439
440impl From<u16> for U256 {
441 fn from(n: u16) -> Self {
442 Self(PrimitiveU256::from(n))
443 }
444}
445
446impl From<u32> for U256 {
447 fn from(n: u32) -> Self {
448 Self(PrimitiveU256::from(n))
449 }
450}
451
452impl From<u64> for U256 {
453 fn from(n: u64) -> Self {
454 Self(PrimitiveU256::from(n))
455 }
456}
457
458impl From<u128> for U256 {
459 fn from(n: u128) -> Self {
460 Self(PrimitiveU256::from(n))
461 }
462}
463
464impl TryFrom<U256> for u8 {
465 type Error = U256CastError;
466 fn try_from(n: U256) -> Result<Self, Self::Error> {
467 let n = n.0.low_u64();
468 if n > Self::MAX as u64 {
469 Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU8))
470 } else {
471 Ok(n as Self)
472 }
473 }
474}
475
476impl TryFrom<U256> for u16 {
477 type Error = U256CastError;
478
479 fn try_from(n: U256) -> Result<Self, Self::Error> {
480 let n = n.0.low_u64();
481 if n > Self::MAX as u64 {
482 Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU16))
483 } else {
484 Ok(n as Self)
485 }
486 }
487}
488
489impl TryFrom<U256> for u32 {
490 type Error = U256CastError;
491
492 fn try_from(n: U256) -> Result<Self, Self::Error> {
493 let n = n.0.low_u64();
494 if n > Self::MAX as u64 {
495 Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU32))
496 } else {
497 Ok(n as Self)
498 }
499 }
500}
501
502impl TryFrom<U256> for u64 {
503 type Error = U256CastError;
504
505 fn try_from(n: U256) -> Result<Self, Self::Error> {
506 let n = n.0.low_u128();
507 if n > Self::MAX as u128 {
508 Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU64))
509 } else {
510 Ok(n as Self)
511 }
512 }
513}
514
515impl TryFrom<U256> for u128 {
516 type Error = U256CastError;
517
518 fn try_from(n: U256) -> Result<Self, Self::Error> {
519 if n > U256::from(Self::MAX) {
520 Err(U256CastError::new(n, U256CastErrorKind::TooLargeForU128))
521 } else {
522 Ok(n.0.low_u128())
523 }
524 }
525}
526
527#[cfg(feature = "proptest")]
530impl proptest::prelude::Arbitrary for U256 {
531 type Strategy = proptest::prelude::BoxedStrategy<Self>;
532 type Parameters = ();
533 fn arbitrary_with(_params: Self::Parameters) -> Self::Strategy {
534 use proptest::strategy::Strategy as _;
535 proptest::arbitrary::any::<[u8; U256_NUM_BYTES]>()
536 .prop_map(|q| Self::from_le_bytes(&q))
537 .boxed()
538 }
539}
540
541#[test]
542#[allow(clippy::unwrap_used)]
543fn wrapping_add() {
544 let a = U256::from(1234u32);
548 let b = U256::from_str_radix(
549 "115792089237316195423570985008687907853269984665640564039457584007913129638801",
550 10,
551 )
552 .unwrap();
553
554 assert!(a.wrapping_add(b) == U256::from(99u8));
555}