1use alloc::{
2 format,
3 string::{String, ToString},
4 vec::Vec,
5};
6use core::{
7 fmt::{self, Formatter},
8 iter::Sum,
9 ops::Add,
10};
11
12use num_integer::Integer;
13use num_traits::{
14 AsPrimitive, Bounded, CheckedAdd, CheckedMul, CheckedSub, Num, One, Unsigned, WrappingAdd,
15 WrappingSub, Zero,
16};
17use rand::{
18 distributions::{Distribution, Standard},
19 Rng,
20};
21use serde::{
22 de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor},
23 ser::{Serialize, SerializeStruct, Serializer},
24};
25
26use crate::bytesrepr::{self, Error, FromBytes, ToBytes, U8_SERIALIZED_LENGTH};
27
28#[allow(
29 clippy::assign_op_pattern,
30 clippy::ptr_offset_with_cast,
31 clippy::manual_range_contains,
32 clippy::range_plus_one,
33 clippy::transmute_ptr_to_ptr,
34 clippy::reversed_empty_ranges
35)]
36mod macro_code {
37 #[cfg(feature = "datasize")]
38 use datasize::DataSize;
39 use uint::construct_uint;
40
41 construct_uint! {
42 #[cfg_attr(feature = "datasize", derive(DataSize))]
43 pub struct U512(8);
44 }
45 construct_uint! {
46 #[cfg_attr(feature = "datasize", derive(DataSize))]
47 pub struct U256(4);
48 }
49 construct_uint! {
50 #[cfg_attr(feature = "datasize", derive(DataSize))]
51 pub struct U128(2);
52 }
53}
54
55pub use self::macro_code::{U128, U256, U512};
56
57#[derive(Debug)]
59#[non_exhaustive]
60pub enum UIntParseError {
61 FromDecStr(uint::FromDecStrErr),
63 InvalidRadix,
67}
68
69macro_rules! impl_traits_for_uint {
70 ($type:ident, $total_bytes:expr, $test_mod:ident) => {
71 impl $type {
72 pub const MIN: $type = $type([0; $total_bytes / 8]);
74 }
75
76 impl Serialize for $type {
77 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
78 if serializer.is_human_readable() {
79 return self.to_string().serialize(serializer);
80 }
81
82 let mut buffer = [0u8; $total_bytes];
83 self.to_little_endian(&mut buffer);
84 let non_zero_bytes: Vec<u8> = buffer
85 .iter()
86 .rev()
87 .skip_while(|b| **b == 0)
88 .cloned()
89 .collect();
90 let num_bytes = non_zero_bytes.len();
91
92 let mut state = serializer.serialize_struct("bigint", num_bytes + 1)?;
93 state.serialize_field("", &(num_bytes as u8))?;
94
95 for byte in non_zero_bytes.into_iter().rev() {
96 state.serialize_field("", &byte)?;
97 }
98 state.end()
99 }
100 }
101
102 impl<'de> Deserialize<'de> for $type {
103 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
104 struct BigNumVisitor;
105
106 impl<'de> Visitor<'de> for BigNumVisitor {
107 type Value = $type;
108
109 fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
110 formatter.write_str("bignum struct")
111 }
112
113 fn visit_seq<V: SeqAccess<'de>>(
114 self,
115 mut sequence: V,
116 ) -> Result<$type, V::Error> {
117 let length: u8 = sequence
118 .next_element()?
119 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
120 let mut buffer = [0u8; $total_bytes];
121 for index in 0..length as usize {
122 let value = sequence
123 .next_element()?
124 .ok_or_else(|| de::Error::invalid_length(index + 1, &self))?;
125 buffer[index as usize] = value;
126 }
127 let result = $type::from_little_endian(&buffer);
128 Ok(result)
129 }
130
131 fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<$type, V::Error> {
132 let _length_key: u8 = map
133 .next_key()?
134 .ok_or_else(|| de::Error::missing_field("length"))?;
135 let length: u8 = map
136 .next_value()
137 .map_err(|_| de::Error::invalid_length(0, &self))?;
138 let mut buffer = [0u8; $total_bytes];
139 for index in 0..length {
140 let _byte_key: u8 = map
141 .next_key()?
142 .ok_or_else(|| de::Error::missing_field("byte"))?;
143 let value = map.next_value().map_err(|_| {
144 de::Error::invalid_length(index as usize + 1, &self)
145 })?;
146 buffer[index as usize] = value;
147 }
148 let result = $type::from_little_endian(&buffer);
149 Ok(result)
150 }
151 }
152
153 const FIELDS: &'static [&'static str] = &[
154 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14",
155 "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27",
156 "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
157 "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53",
158 "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64",
159 ];
160
161 if deserializer.is_human_readable() {
162 let decimal_string = String::deserialize(deserializer)?;
163 return Self::from_dec_str(&decimal_string)
164 .map_err(|error| de::Error::custom(format!("{:?}", error)));
165 }
166
167 deserializer.deserialize_struct("bigint", FIELDS, BigNumVisitor)
168 }
169 }
170
171 impl ToBytes for $type {
172 fn to_bytes(&self) -> Result<Vec<u8>, Error> {
173 let mut buf = [0u8; $total_bytes];
174 self.to_little_endian(&mut buf);
175 let mut non_zero_bytes: Vec<u8> =
176 buf.iter().rev().skip_while(|b| **b == 0).cloned().collect();
177 let num_bytes = non_zero_bytes.len() as u8;
178 non_zero_bytes.push(num_bytes);
179 non_zero_bytes.reverse();
180 Ok(non_zero_bytes)
181 }
182
183 fn serialized_length(&self) -> usize {
184 let mut buf = [0u8; $total_bytes];
185 self.to_little_endian(&mut buf);
186 let non_zero_bytes = buf.iter().rev().skip_while(|b| **b == 0).count();
187 U8_SERIALIZED_LENGTH + non_zero_bytes
188 }
189 }
190
191 impl FromBytes for $type {
192 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
193 let (num_bytes, rem): (u8, &[u8]) = FromBytes::from_bytes(bytes)?;
194
195 if num_bytes > $total_bytes {
196 Err(Error::Formatting)
197 } else {
198 let (value, rem) = bytesrepr::safe_split_at(rem, num_bytes as usize)?;
199 let result = $type::from_little_endian(value);
200 Ok((result, rem))
201 }
202 }
203 }
204
205 impl Zero for $type {
207 fn zero() -> Self {
208 $type::zero()
209 }
210
211 fn is_zero(&self) -> bool {
212 self.is_zero()
213 }
214 }
215
216 impl One for $type {
217 fn one() -> Self {
218 $type::one()
219 }
220 }
221
222 impl Num for $type {
224 type FromStrRadixErr = UIntParseError;
225 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
226 if radix == 10 {
227 $type::from_dec_str(str).map_err(UIntParseError::FromDecStr)
228 } else {
229 Err(UIntParseError::InvalidRadix)
231 }
232 }
233 }
234
235 impl Unsigned for $type {}
237
238 impl Bounded for $type {
240 fn min_value() -> Self {
241 $type::zero()
242 }
243
244 fn max_value() -> Self {
245 $type::MAX
246 }
247 }
248
249 impl WrappingAdd for $type {
252 fn wrapping_add(&self, other: &$type) -> $type {
253 self.overflowing_add(*other).0
254 }
255 }
256
257 impl WrappingSub for $type {
258 fn wrapping_sub(&self, other: &$type) -> $type {
259 self.overflowing_sub(*other).0
260 }
261 }
262
263 impl CheckedMul for $type {
264 fn checked_mul(&self, v: &$type) -> Option<$type> {
265 $type::checked_mul(*self, *v)
266 }
267 }
268
269 impl CheckedSub for $type {
270 fn checked_sub(&self, v: &$type) -> Option<$type> {
271 $type::checked_sub(*self, *v)
272 }
273 }
274
275 impl CheckedAdd for $type {
276 fn checked_add(&self, v: &$type) -> Option<$type> {
277 $type::checked_add(*self, *v)
278 }
279 }
280
281 impl Integer for $type {
282 #[inline]
284 fn div_floor(&self, other: &Self) -> Self {
285 *self / *other
286 }
287
288 #[inline]
290 fn mod_floor(&self, other: &Self) -> Self {
291 *self % *other
292 }
293
294 #[inline]
296 fn gcd(&self, other: &Self) -> Self {
297 let zero = Self::zero();
298 let mut m = *self;
300 let mut n = *other;
301 if m == zero || n == zero {
302 return m | n;
303 }
304
305 let shift = (m | n).trailing_zeros();
307
308 m >>= m.trailing_zeros();
310 n >>= n.trailing_zeros();
311
312 while m != n {
313 if m > n {
314 m -= n;
315 m >>= m.trailing_zeros();
316 } else {
317 n -= m;
318 n >>= n.trailing_zeros();
319 }
320 }
321 m << shift
322 }
323
324 #[inline]
326 fn lcm(&self, other: &Self) -> Self {
327 self.gcd_lcm(other).1
328 }
329
330 #[inline]
333 fn gcd_lcm(&self, other: &Self) -> (Self, Self) {
334 if self.is_zero() && other.is_zero() {
335 return (Self::zero(), Self::zero());
336 }
337 let gcd = self.gcd(other);
338 let lcm = *self * (*other / gcd);
339 (gcd, lcm)
340 }
341
342 #[inline]
344 fn divides(&self, other: &Self) -> bool {
345 self.is_multiple_of(other)
346 }
347
348 #[inline]
350 fn is_multiple_of(&self, other: &Self) -> bool {
351 *self % *other == $type::zero()
352 }
353
354 #[inline]
356 fn is_even(&self) -> bool {
357 (self.0[0]) & 1 == 0
358 }
359
360 #[inline]
362 fn is_odd(&self) -> bool {
363 !self.is_even()
364 }
365
366 #[inline]
368 fn div_rem(&self, other: &Self) -> (Self, Self) {
369 (*self / *other, *self % *other)
370 }
371 }
372
373 impl AsPrimitive<$type> for i32 {
374 fn as_(self) -> $type {
375 if self >= 0 {
376 $type::from(self as u32)
377 } else {
378 let abs = 0u32.wrapping_sub(self as u32);
379 $type::zero().wrapping_sub(&$type::from(abs))
380 }
381 }
382 }
383
384 impl AsPrimitive<$type> for i64 {
385 fn as_(self) -> $type {
386 if self >= 0 {
387 $type::from(self as u64)
388 } else {
389 let abs = 0u64.wrapping_sub(self as u64);
390 $type::zero().wrapping_sub(&$type::from(abs))
391 }
392 }
393 }
394
395 impl AsPrimitive<$type> for u8 {
396 fn as_(self) -> $type {
397 $type::from(self)
398 }
399 }
400
401 impl AsPrimitive<$type> for u32 {
402 fn as_(self) -> $type {
403 $type::from(self)
404 }
405 }
406
407 impl AsPrimitive<$type> for u64 {
408 fn as_(self) -> $type {
409 $type::from(self)
410 }
411 }
412
413 impl AsPrimitive<i32> for $type {
414 fn as_(self) -> i32 {
415 self.0[0] as i32
416 }
417 }
418
419 impl AsPrimitive<i64> for $type {
420 fn as_(self) -> i64 {
421 self.0[0] as i64
422 }
423 }
424
425 impl AsPrimitive<u8> for $type {
426 fn as_(self) -> u8 {
427 self.0[0] as u8
428 }
429 }
430
431 impl AsPrimitive<u32> for $type {
432 fn as_(self) -> u32 {
433 self.0[0] as u32
434 }
435 }
436
437 impl AsPrimitive<u64> for $type {
438 fn as_(self) -> u64 {
439 self.0[0]
440 }
441 }
442
443 impl Sum for $type {
444 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
445 iter.fold($type::zero(), Add::add)
446 }
447 }
448
449 impl Distribution<$type> for Standard {
450 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $type {
451 let mut raw_bytes = [0u8; $total_bytes];
452 rng.fill_bytes(raw_bytes.as_mut());
453 $type::from(raw_bytes)
454 }
455 }
456
457 #[cfg(feature = "json-schema")]
458 impl schemars::JsonSchema for $type {
459 fn schema_name() -> String {
460 format!("U{}", $total_bytes * 8)
461 }
462
463 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
464 let schema = gen.subschema_for::<String>();
465 let mut schema_object = schema.into_object();
466 schema_object.metadata().description = Some(format!(
467 "Decimal representation of a {}-bit integer.",
468 $total_bytes * 8
469 ));
470 schema_object.into()
471 }
472 }
473
474 #[cfg(test)]
475 mod $test_mod {
476 use super::*;
477
478 #[test]
479 fn test_div_mod_floor() {
480 assert_eq!($type::from(10).div_floor(&$type::from(3)), $type::from(3));
481 assert_eq!($type::from(10).mod_floor(&$type::from(3)), $type::from(1));
482 assert_eq!(
483 $type::from(10).div_mod_floor(&$type::from(3)),
484 ($type::from(3), $type::from(1))
485 );
486 assert_eq!($type::from(5).div_floor(&$type::from(5)), $type::from(1));
487 assert_eq!($type::from(5).mod_floor(&$type::from(5)), $type::from(0));
488 assert_eq!(
489 $type::from(5).div_mod_floor(&$type::from(5)),
490 ($type::from(1), $type::from(0))
491 );
492 assert_eq!($type::from(3).div_floor(&$type::from(7)), $type::from(0));
493 assert_eq!($type::from(3).mod_floor(&$type::from(7)), $type::from(3));
494 assert_eq!(
495 $type::from(3).div_mod_floor(&$type::from(7)),
496 ($type::from(0), $type::from(3))
497 );
498 }
499
500 #[test]
501 fn test_gcd() {
502 assert_eq!($type::from(10).gcd(&$type::from(2)), $type::from(2));
503 assert_eq!($type::from(10).gcd(&$type::from(3)), $type::from(1));
504 assert_eq!($type::from(0).gcd(&$type::from(3)), $type::from(3));
505 assert_eq!($type::from(3).gcd(&$type::from(3)), $type::from(3));
506 assert_eq!($type::from(56).gcd(&$type::from(42)), $type::from(14));
507 assert_eq!(
508 $type::MAX.gcd(&($type::MAX / $type::from(2))),
509 $type::from(1)
510 );
511 assert_eq!($type::from(15).gcd(&$type::from(17)), $type::from(1));
512 }
513
514 #[test]
515 fn test_lcm() {
516 assert_eq!($type::from(1).lcm(&$type::from(0)), $type::from(0));
517 assert_eq!($type::from(0).lcm(&$type::from(1)), $type::from(0));
518 assert_eq!($type::from(1).lcm(&$type::from(1)), $type::from(1));
519 assert_eq!($type::from(8).lcm(&$type::from(9)), $type::from(72));
520 assert_eq!($type::from(11).lcm(&$type::from(5)), $type::from(55));
521 assert_eq!($type::from(15).lcm(&$type::from(17)), $type::from(255));
522 assert_eq!($type::from(4).lcm(&$type::from(8)), $type::from(8));
523 }
524
525 #[test]
526 fn test_is_multiple_of() {
527 assert!($type::from(6).is_multiple_of(&$type::from(6)));
528 assert!($type::from(6).is_multiple_of(&$type::from(3)));
529 assert!($type::from(6).is_multiple_of(&$type::from(1)));
530 assert!(!$type::from(3).is_multiple_of(&$type::from(5)))
531 }
532
533 #[test]
534 fn is_even() {
535 assert_eq!($type::from(0).is_even(), true);
536 assert_eq!($type::from(1).is_even(), false);
537 assert_eq!($type::from(2).is_even(), true);
538 assert_eq!($type::from(3).is_even(), false);
539 assert_eq!($type::from(4).is_even(), true);
540 }
541
542 #[test]
543 fn is_odd() {
544 assert_eq!($type::from(0).is_odd(), false);
545 assert_eq!($type::from(1).is_odd(), true);
546 assert_eq!($type::from(2).is_odd(), false);
547 assert_eq!($type::from(3).is_odd(), true);
548 assert_eq!($type::from(4).is_odd(), false);
549 }
550
551 #[test]
552 #[should_panic]
553 fn overflow_mul_test() {
554 let _ = $type::MAX * $type::from(2);
555 }
556
557 #[test]
558 #[should_panic]
559 fn overflow_add_test() {
560 let _ = $type::MAX + $type::from(1);
561 }
562
563 #[test]
564 #[should_panic]
565 fn underflow_sub_test() {
566 let _ = $type::zero() - $type::from(1);
567 }
568 }
569 };
570}
571
572impl_traits_for_uint!(U128, 16, u128_test);
573impl_traits_for_uint!(U256, 32, u256_test);
574impl_traits_for_uint!(U512, 64, u512_test);
575
576impl AsPrimitive<U128> for U128 {
577 fn as_(self) -> U128 {
578 self
579 }
580}
581
582impl AsPrimitive<U256> for U128 {
583 fn as_(self) -> U256 {
584 let mut result = U256::zero();
585 result.0[..2].clone_from_slice(&self.0[..2]);
586 result
587 }
588}
589
590impl AsPrimitive<U512> for U128 {
591 fn as_(self) -> U512 {
592 let mut result = U512::zero();
593 result.0[..2].clone_from_slice(&self.0[..2]);
594 result
595 }
596}
597
598impl AsPrimitive<U128> for U256 {
599 fn as_(self) -> U128 {
600 let mut result = U128::zero();
601 result.0[..2].clone_from_slice(&self.0[..2]);
602 result
603 }
604}
605
606impl AsPrimitive<U256> for U256 {
607 fn as_(self) -> U256 {
608 self
609 }
610}
611
612impl AsPrimitive<U512> for U256 {
613 fn as_(self) -> U512 {
614 let mut result = U512::zero();
615 result.0[..4].clone_from_slice(&self.0[..4]);
616 result
617 }
618}
619
620impl AsPrimitive<U128> for U512 {
621 fn as_(self) -> U128 {
622 let mut result = U128::zero();
623 result.0[..2].clone_from_slice(&self.0[..2]);
624 result
625 }
626}
627
628impl AsPrimitive<U256> for U512 {
629 fn as_(self) -> U256 {
630 let mut result = U256::zero();
631 result.0[..4].clone_from_slice(&self.0[..4]);
632 result
633 }
634}
635
636impl AsPrimitive<U512> for U512 {
637 fn as_(self) -> U512 {
638 self
639 }
640}
641
642#[cfg(test)]
643mod tests {
644 use std::fmt::Debug;
645
646 use serde::de::DeserializeOwned;
647
648 use super::*;
649
650 fn check_as_i32<T: AsPrimitive<i32>>(expected: i32, input: T) {
651 assert_eq!(expected, input.as_());
652 }
653
654 fn check_as_i64<T: AsPrimitive<i64>>(expected: i64, input: T) {
655 assert_eq!(expected, input.as_());
656 }
657
658 fn check_as_u8<T: AsPrimitive<u8>>(expected: u8, input: T) {
659 assert_eq!(expected, input.as_());
660 }
661
662 fn check_as_u32<T: AsPrimitive<u32>>(expected: u32, input: T) {
663 assert_eq!(expected, input.as_());
664 }
665
666 fn check_as_u64<T: AsPrimitive<u64>>(expected: u64, input: T) {
667 assert_eq!(expected, input.as_());
668 }
669
670 fn check_as_u128<T: AsPrimitive<U128>>(expected: U128, input: T) {
671 assert_eq!(expected, input.as_());
672 }
673
674 fn check_as_u256<T: AsPrimitive<U256>>(expected: U256, input: T) {
675 assert_eq!(expected, input.as_());
676 }
677
678 fn check_as_u512<T: AsPrimitive<U512>>(expected: U512, input: T) {
679 assert_eq!(expected, input.as_());
680 }
681
682 #[test]
683 fn as_primitive_from_i32() {
684 let mut input = 0_i32;
685 check_as_i32(0, input);
686 check_as_i64(0, input);
687 check_as_u8(0, input);
688 check_as_u32(0, input);
689 check_as_u64(0, input);
690 check_as_u128(U128::zero(), input);
691 check_as_u256(U256::zero(), input);
692 check_as_u512(U512::zero(), input);
693
694 input = i32::MAX - 1;
695 check_as_i32(input, input);
696 check_as_i64(i64::from(input), input);
697 check_as_u8(input as u8, input);
698 check_as_u32(input as u32, input);
699 check_as_u64(input as u64, input);
700 check_as_u128(U128::from(input), input);
701 check_as_u256(U256::from(input), input);
702 check_as_u512(U512::from(input), input);
703
704 input = i32::MIN + 1;
705 check_as_i32(input, input);
706 check_as_i64(i64::from(input), input);
707 check_as_u8(input as u8, input);
708 check_as_u32(input as u32, input);
709 check_as_u64(input as u64, input);
710 check_as_u128(U128::zero().wrapping_sub(&U128::from(i32::MAX)), input);
712 check_as_u256(U256::zero().wrapping_sub(&U256::from(i32::MAX)), input);
713 check_as_u512(U512::zero().wrapping_sub(&U512::from(i32::MAX)), input);
714 }
715
716 #[test]
717 fn as_primitive_from_i64() {
718 let mut input = 0_i64;
719 check_as_i32(0, input);
720 check_as_i64(0, input);
721 check_as_u8(0, input);
722 check_as_u32(0, input);
723 check_as_u64(0, input);
724 check_as_u128(U128::zero(), input);
725 check_as_u256(U256::zero(), input);
726 check_as_u512(U512::zero(), input);
727
728 input = i64::MAX - 1;
729 check_as_i32(input as i32, input);
730 check_as_i64(input, input);
731 check_as_u8(input as u8, input);
732 check_as_u32(input as u32, input);
733 check_as_u64(input as u64, input);
734 check_as_u128(U128::from(input), input);
735 check_as_u256(U256::from(input), input);
736 check_as_u512(U512::from(input), input);
737
738 input = i64::MIN + 1;
739 check_as_i32(input as i32, input);
740 check_as_i64(input, input);
741 check_as_u8(input as u8, input);
742 check_as_u32(input as u32, input);
743 check_as_u64(input as u64, input);
744 check_as_u128(U128::zero().wrapping_sub(&U128::from(i64::MAX)), input);
746 check_as_u256(U256::zero().wrapping_sub(&U256::from(i64::MAX)), input);
747 check_as_u512(U512::zero().wrapping_sub(&U512::from(i64::MAX)), input);
748 }
749
750 #[test]
751 fn as_primitive_from_u8() {
752 let mut input = 0_u8;
753 check_as_i32(0, input);
754 check_as_i64(0, input);
755 check_as_u8(0, input);
756 check_as_u32(0, input);
757 check_as_u64(0, input);
758 check_as_u128(U128::zero(), input);
759 check_as_u256(U256::zero(), input);
760 check_as_u512(U512::zero(), input);
761
762 input = u8::MAX - 1;
763 check_as_i32(i32::from(input), input);
764 check_as_i64(i64::from(input), input);
765 check_as_u8(input, input);
766 check_as_u32(u32::from(input), input);
767 check_as_u64(u64::from(input), input);
768 check_as_u128(U128::from(input), input);
769 check_as_u256(U256::from(input), input);
770 check_as_u512(U512::from(input), input);
771 }
772
773 #[test]
774 fn as_primitive_from_u32() {
775 let mut input = 0_u32;
776 check_as_i32(0, input);
777 check_as_i64(0, input);
778 check_as_u8(0, input);
779 check_as_u32(0, input);
780 check_as_u64(0, input);
781 check_as_u128(U128::zero(), input);
782 check_as_u256(U256::zero(), input);
783 check_as_u512(U512::zero(), input);
784
785 input = u32::MAX - 1;
786 check_as_i32(input as i32, input);
787 check_as_i64(i64::from(input), input);
788 check_as_u8(input as u8, input);
789 check_as_u32(input, input);
790 check_as_u64(u64::from(input), input);
791 check_as_u128(U128::from(input), input);
792 check_as_u256(U256::from(input), input);
793 check_as_u512(U512::from(input), input);
794 }
795
796 #[test]
797 fn as_primitive_from_u64() {
798 let mut input = 0_u64;
799 check_as_i32(0, input);
800 check_as_i64(0, input);
801 check_as_u8(0, input);
802 check_as_u32(0, input);
803 check_as_u64(0, input);
804 check_as_u128(U128::zero(), input);
805 check_as_u256(U256::zero(), input);
806 check_as_u512(U512::zero(), input);
807
808 input = u64::MAX - 1;
809 check_as_i32(input as i32, input);
810 check_as_i64(input as i64, input);
811 check_as_u8(input as u8, input);
812 check_as_u32(input as u32, input);
813 check_as_u64(input, input);
814 check_as_u128(U128::from(input), input);
815 check_as_u256(U256::from(input), input);
816 check_as_u512(U512::from(input), input);
817 }
818
819 fn make_little_endian_arrays(little_endian_bytes: &[u8]) -> ([u8; 4], [u8; 8]) {
820 let le_32 = {
821 let mut le_32 = [0; 4];
822 le_32.copy_from_slice(&little_endian_bytes[..4]);
823 le_32
824 };
825
826 let le_64 = {
827 let mut le_64 = [0; 8];
828 le_64.copy_from_slice(&little_endian_bytes[..8]);
829 le_64
830 };
831
832 (le_32, le_64)
833 }
834
835 #[test]
836 fn as_primitive_from_u128() {
837 let mut input = U128::zero();
838 check_as_i32(0, input);
839 check_as_i64(0, input);
840 check_as_u8(0, input);
841 check_as_u32(0, input);
842 check_as_u64(0, input);
843 check_as_u128(U128::zero(), input);
844 check_as_u256(U256::zero(), input);
845 check_as_u512(U512::zero(), input);
846
847 input = U128::MAX - 1;
848
849 let mut little_endian_bytes = [0_u8; 64];
850 input.to_little_endian(&mut little_endian_bytes[..16]);
851 let (le_32, le_64) = make_little_endian_arrays(&little_endian_bytes);
852
853 check_as_i32(i32::from_le_bytes(le_32), input);
854 check_as_i64(i64::from_le_bytes(le_64), input);
855 check_as_u8(little_endian_bytes[0], input);
856 check_as_u32(u32::from_le_bytes(le_32), input);
857 check_as_u64(u64::from_le_bytes(le_64), input);
858 check_as_u128(U128::from_little_endian(&little_endian_bytes[..16]), input);
859 check_as_u256(U256::from_little_endian(&little_endian_bytes[..32]), input);
860 check_as_u512(U512::from_little_endian(&little_endian_bytes), input);
861 }
862
863 #[test]
864 fn as_primitive_from_u256() {
865 let mut input = U256::zero();
866 check_as_i32(0, input);
867 check_as_i64(0, input);
868 check_as_u8(0, input);
869 check_as_u32(0, input);
870 check_as_u64(0, input);
871 check_as_u128(U128::zero(), input);
872 check_as_u256(U256::zero(), input);
873 check_as_u512(U512::zero(), input);
874
875 input = U256::MAX - 1;
876
877 let mut little_endian_bytes = [0_u8; 64];
878 input.to_little_endian(&mut little_endian_bytes[..32]);
879 let (le_32, le_64) = make_little_endian_arrays(&little_endian_bytes);
880
881 check_as_i32(i32::from_le_bytes(le_32), input);
882 check_as_i64(i64::from_le_bytes(le_64), input);
883 check_as_u8(little_endian_bytes[0], input);
884 check_as_u32(u32::from_le_bytes(le_32), input);
885 check_as_u64(u64::from_le_bytes(le_64), input);
886 check_as_u128(U128::from_little_endian(&little_endian_bytes[..16]), input);
887 check_as_u256(U256::from_little_endian(&little_endian_bytes[..32]), input);
888 check_as_u512(U512::from_little_endian(&little_endian_bytes), input);
889 }
890
891 #[test]
892 fn as_primitive_from_u512() {
893 let mut input = U512::zero();
894 check_as_i32(0, input);
895 check_as_i64(0, input);
896 check_as_u8(0, input);
897 check_as_u32(0, input);
898 check_as_u64(0, input);
899 check_as_u128(U128::zero(), input);
900 check_as_u256(U256::zero(), input);
901 check_as_u512(U512::zero(), input);
902
903 input = U512::MAX - 1;
904
905 let mut little_endian_bytes = [0_u8; 64];
906 input.to_little_endian(&mut little_endian_bytes);
907 let (le_32, le_64) = make_little_endian_arrays(&little_endian_bytes);
908
909 check_as_i32(i32::from_le_bytes(le_32), input);
910 check_as_i64(i64::from_le_bytes(le_64), input);
911 check_as_u8(little_endian_bytes[0], input);
912 check_as_u32(u32::from_le_bytes(le_32), input);
913 check_as_u64(u64::from_le_bytes(le_64), input);
914 check_as_u128(U128::from_little_endian(&little_endian_bytes[..16]), input);
915 check_as_u256(U256::from_little_endian(&little_endian_bytes[..32]), input);
916 check_as_u512(U512::from_little_endian(&little_endian_bytes), input);
917 }
918
919 #[test]
920 fn wrapping_test_u512() {
921 let max = U512::MAX;
922 let value = max.wrapping_add(&1.into());
923 assert_eq!(value, 0.into());
924
925 let min = U512::MIN;
926 let value = min.wrapping_sub(&1.into());
927 assert_eq!(value, U512::MAX);
928 }
929
930 #[test]
931 fn wrapping_test_u256() {
932 let max = U256::MAX;
933 let value = max.wrapping_add(&1.into());
934 assert_eq!(value, 0.into());
935
936 let min = U256::MIN;
937 let value = min.wrapping_sub(&1.into());
938 assert_eq!(value, U256::MAX);
939 }
940
941 #[test]
942 fn wrapping_test_u128() {
943 let max = U128::MAX;
944 let value = max.wrapping_add(&1.into());
945 assert_eq!(value, 0.into());
946
947 let min = U128::MIN;
948 let value = min.wrapping_sub(&1.into());
949 assert_eq!(value, U128::MAX);
950 }
951
952 fn serde_roundtrip<T: Serialize + DeserializeOwned + Eq + Debug>(value: T) {
953 {
954 let serialized = bincode::serialize(&value).unwrap();
955 let deserialized = bincode::deserialize(serialized.as_slice()).unwrap();
956 assert_eq!(value, deserialized);
957 }
958 {
959 let serialized = serde_json::to_string_pretty(&value).unwrap();
960 let deserialized = serde_json::from_str(&serialized).unwrap();
961 assert_eq!(value, deserialized);
962 }
963 }
964
965 #[test]
966 fn serde_roundtrip_u512() {
967 serde_roundtrip(U512::MIN);
968 serde_roundtrip(U512::from(1));
969 serde_roundtrip(U512::from(u64::MAX));
970 serde_roundtrip(U512::MAX);
971 }
972
973 #[test]
974 fn serde_roundtrip_u256() {
975 serde_roundtrip(U256::MIN);
976 serde_roundtrip(U256::from(1));
977 serde_roundtrip(U256::from(u64::MAX));
978 serde_roundtrip(U256::MAX);
979 }
980
981 #[test]
982 fn serde_roundtrip_u128() {
983 serde_roundtrip(U128::MIN);
984 serde_roundtrip(U128::from(1));
985 serde_roundtrip(U128::from(u64::MAX));
986 serde_roundtrip(U128::MAX);
987 }
988
989 #[test]
990 fn safe_conversion_from_u512_to_u64() {
991 let mut value = U512::from(u64::MAX);
992 assert_eq!(value.try_into(), Ok(u64::MAX));
993 value += U512::one();
994 assert!(
995 matches!(value.try_into(), Result::<u64, _>::Err(_)),
996 "integer overflow when casting to u64"
997 );
998 }
999}