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