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