casper_types/
uint.rs

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/// Error type for parsing [`U128`], [`U256`], [`U512`] from a string.
58#[derive(Debug)]
59#[non_exhaustive]
60pub enum UIntParseError {
61    /// Contains the parsing error from the `uint` crate, which only supports base-10 parsing.
62    FromDecStr(uint::FromDecStrErr),
63    /// Parsing was attempted on a string representing the number in some base other than 10.
64    ///
65    /// Note: a general radix may be supported in the future.
66    InvalidRadix,
67}
68
69macro_rules! impl_traits_for_uint {
70    ($type:ident, $total_bytes:expr, $test_mod:ident) => {
71        impl $type {
72            /// The smallest value that can be represented by this type.
73            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        // Trait implementations for unifying U* as numeric types
206        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        // Requires Zero and One to be implemented
223        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                    // TODO: other radix parsing
230                    Err(UIntParseError::InvalidRadix)
231                }
232            }
233        }
234
235        // Requires Num to be implemented
236        impl Unsigned for $type {}
237
238        // Additional numeric trait, which also holds for these types
239        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        // Instead of implementing arbitrary methods we can use existing traits from num_trait
250        // crate.
251        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            /// Unsigned integer division. Returns the same result as `div` (`/`).
283            #[inline]
284            fn div_floor(&self, other: &Self) -> Self {
285                *self / *other
286            }
287
288            /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
289            #[inline]
290            fn mod_floor(&self, other: &Self) -> Self {
291                *self % *other
292            }
293
294            /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
295            #[inline]
296            fn gcd(&self, other: &Self) -> Self {
297                let zero = Self::zero();
298                // Use Stein's algorithm
299                let mut m = *self;
300                let mut n = *other;
301                if m == zero || n == zero {
302                    return m | n;
303                }
304
305                // find common factors of 2
306                let shift = (m | n).trailing_zeros();
307
308                // divide n and m by 2 until odd
309                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            /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
325            #[inline]
326            fn lcm(&self, other: &Self) -> Self {
327                self.gcd_lcm(other).1
328            }
329
330            /// Calculates the Greatest Common Divisor (GCD) and
331            /// Lowest Common Multiple (LCM) of the number and `other`.
332            #[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            /// Deprecated, use `is_multiple_of` instead.
343            #[inline]
344            fn divides(&self, other: &Self) -> bool {
345                self.is_multiple_of(other)
346            }
347
348            /// Returns `true` if the number is a multiple of `other`.
349            #[inline]
350            fn is_multiple_of(&self, other: &Self) -> bool {
351                *self % *other == $type::zero()
352            }
353
354            /// Returns `true` if the number is divisible by `2`.
355            #[inline]
356            fn is_even(&self) -> bool {
357                (self.0[0]) & 1 == 0
358            }
359
360            /// Returns `true` if the number is not divisible by `2`.
361            #[inline]
362            fn is_odd(&self) -> bool {
363                !self.is_even()
364            }
365
366            /// Simultaneous truncated integer division and modulus.
367            #[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        // i32::MIN is -1 - i32::MAX
711        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        // i64::MIN is (-1 - i64::MAX)
745        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}