1use forward_ref::{forward_ref_binop, forward_ref_op_assign};
2use schemars::JsonSchema;
3use serde::{de, ser, Deserialize, Deserializer, Serialize};
4use std::fmt;
5use std::ops::{
6 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shr, ShrAssign, Sub, SubAssign,
7};
8use std::str::FromStr;
9
10use crate::errors::{
11 ConversionOverflowError, DivideByZeroError, OverflowError, OverflowOperation, StdError,
12};
13use crate::{Uint128, Uint256, Uint64};
14
15#[allow(clippy::all)]
18mod uints {
19 uint::construct_uint! {
20 pub struct U512(8);
21 }
22}
23
24use uints::U512;
27
28#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
53pub struct Uint512(#[schemars(with = "String")] U512);
54
55impl Uint512 {
56 pub const MAX: Uint512 = Uint512(U512::MAX);
57 pub const MIN: Uint512 = Uint512(U512::zero());
58
59 pub const fn new(value: [u8; 64]) -> Self {
62 Self::from_be_bytes(value)
63 }
64
65 #[inline]
67 pub const fn zero() -> Self {
68 Uint512(U512::zero())
69 }
70
71 #[inline]
73 pub const fn one() -> Self {
74 Self::from_be_bytes([
75 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 1,
78 ])
79 }
80
81 pub const fn from_be_bytes(data: [u8; 64]) -> Self {
82 let words: [u64; 8] = [
83 u64::from_le_bytes([
84 data[63], data[62], data[61], data[60], data[59], data[58], data[57], data[56],
85 ]),
86 u64::from_le_bytes([
87 data[55], data[54], data[53], data[52], data[51], data[50], data[49], data[48],
88 ]),
89 u64::from_le_bytes([
90 data[47], data[46], data[45], data[44], data[43], data[42], data[41], data[40],
91 ]),
92 u64::from_le_bytes([
93 data[39], data[38], data[37], data[36], data[35], data[34], data[33], data[32],
94 ]),
95 u64::from_le_bytes([
96 data[31], data[30], data[29], data[28], data[27], data[26], data[25], data[24],
97 ]),
98 u64::from_le_bytes([
99 data[23], data[22], data[21], data[20], data[19], data[18], data[17], data[16],
100 ]),
101 u64::from_le_bytes([
102 data[15], data[14], data[13], data[12], data[11], data[10], data[9], data[8],
103 ]),
104 u64::from_le_bytes([
105 data[7], data[6], data[5], data[4], data[3], data[2], data[1], data[0],
106 ]),
107 ];
108 Self(U512(words))
109 }
110
111 pub const fn from_le_bytes(data: [u8; 64]) -> Self {
112 let words: [u64; 8] = [
113 u64::from_le_bytes([
114 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
115 ]),
116 u64::from_le_bytes([
117 data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15],
118 ]),
119 u64::from_le_bytes([
120 data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23],
121 ]),
122 u64::from_le_bytes([
123 data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31],
124 ]),
125 u64::from_le_bytes([
126 data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39],
127 ]),
128 u64::from_le_bytes([
129 data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47],
130 ]),
131 u64::from_le_bytes([
132 data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55],
133 ]),
134 u64::from_le_bytes([
135 data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63],
136 ]),
137 ];
138 Self(U512(words))
139 }
140
141 pub const fn from_uint256(num: Uint256) -> Self {
144 let bytes = num.to_le_bytes();
145 Self::from_le_bytes([
146 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
147 bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
148 bytes[16], bytes[17], bytes[18], bytes[19], bytes[20], bytes[21], bytes[22], bytes[23],
149 bytes[24], bytes[25], bytes[26], bytes[27], bytes[28], bytes[29], bytes[30], bytes[31],
150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
151 0, 0, 0,
152 ])
153 }
154
155 pub const fn to_be_bytes(self) -> [u8; 64] {
157 let words = [
158 (self.0).0[7].to_be_bytes(),
159 (self.0).0[6].to_be_bytes(),
160 (self.0).0[5].to_be_bytes(),
161 (self.0).0[4].to_be_bytes(),
162 (self.0).0[3].to_be_bytes(),
163 (self.0).0[2].to_be_bytes(),
164 (self.0).0[1].to_be_bytes(),
165 (self.0).0[0].to_be_bytes(),
166 ];
167 unsafe { std::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) }
168 }
169
170 pub const fn to_le_bytes(self) -> [u8; 64] {
172 let words = [
173 (self.0).0[0].to_le_bytes(),
174 (self.0).0[1].to_le_bytes(),
175 (self.0).0[2].to_le_bytes(),
176 (self.0).0[3].to_le_bytes(),
177 (self.0).0[4].to_le_bytes(),
178 (self.0).0[5].to_le_bytes(),
179 (self.0).0[6].to_le_bytes(),
180 (self.0).0[7].to_le_bytes(),
181 ];
182 unsafe { std::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) }
183 }
184
185 pub const fn is_zero(&self) -> bool {
186 let words = (self.0).0;
187 words[0] == 0
188 && words[1] == 0
189 && words[2] == 0
190 && words[3] == 0
191 && words[4] == 0
192 && words[5] == 0
193 && words[6] == 0
194 && words[7] == 0
195 }
196
197 pub fn pow(self, exp: u32) -> Self {
198 let res = self.0.pow(exp.into());
199 Self(res)
200 }
201
202 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
203 self.0
204 .checked_add(other.0)
205 .map(Self)
206 .ok_or_else(|| OverflowError::new(OverflowOperation::Add, self, other))
207 }
208
209 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
210 self.0
211 .checked_sub(other.0)
212 .map(Self)
213 .ok_or_else(|| OverflowError::new(OverflowOperation::Sub, self, other))
214 }
215
216 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
217 self.0
218 .checked_mul(other.0)
219 .map(Self)
220 .ok_or_else(|| OverflowError::new(OverflowOperation::Mul, self, other))
221 }
222
223 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
224 self.0
225 .checked_pow(exp.into())
226 .map(Self)
227 .ok_or_else(|| OverflowError::new(OverflowOperation::Pow, self, exp))
228 }
229
230 pub fn checked_div(self, other: Self) -> Result<Self, DivideByZeroError> {
231 self.0
232 .checked_div(other.0)
233 .map(Self)
234 .ok_or_else(|| DivideByZeroError::new(self))
235 }
236
237 pub fn checked_div_euclid(self, other: Self) -> Result<Self, DivideByZeroError> {
238 self.checked_div(other)
239 }
240
241 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
242 self.0
243 .checked_rem(other.0)
244 .map(Self)
245 .ok_or_else(|| DivideByZeroError::new(self))
246 }
247
248 pub fn checked_shr(self, other: u32) -> Result<Self, OverflowError> {
249 if other >= 512 {
250 return Err(OverflowError::new(OverflowOperation::Shr, self, other));
251 }
252
253 Ok(Self(self.0.shr(other)))
254 }
255
256 #[inline]
257 pub fn wrapping_add(self, other: Self) -> Self {
258 let (value, _did_overflow) = self.0.overflowing_add(other.0);
259 Self(value)
260 }
261
262 #[inline]
263 pub fn wrapping_sub(self, other: Self) -> Self {
264 let (value, _did_overflow) = self.0.overflowing_sub(other.0);
265 Self(value)
266 }
267
268 #[inline]
269 pub fn wrapping_mul(self, other: Self) -> Self {
270 let (value, _did_overflow) = self.0.overflowing_mul(other.0);
271 Self(value)
272 }
273
274 #[inline]
275 pub fn wrapping_pow(self, other: u32) -> Self {
276 let (value, _did_overflow) = self.0.overflowing_pow(other.into());
277 Self(value)
278 }
279
280 pub fn saturating_add(self, other: Self) -> Self {
281 Self(self.0.saturating_add(other.0))
282 }
283
284 pub fn saturating_sub(self, other: Self) -> Self {
285 Self(self.0.saturating_sub(other.0))
286 }
287
288 pub fn saturating_mul(self, other: Self) -> Self {
289 Self(self.0.saturating_mul(other.0))
290 }
291
292 pub fn saturating_pow(self, exp: u32) -> Self {
293 match self.checked_pow(exp) {
294 Ok(value) => value,
295 Err(_) => Self::MAX,
296 }
297 }
298
299 pub fn abs_diff(self, other: Self) -> Self {
300 if self < other {
301 other - self
302 } else {
303 self - other
304 }
305 }
306}
307
308impl From<Uint256> for Uint512 {
309 fn from(val: Uint256) -> Self {
310 let bytes = [[0u8; 32], val.to_be_bytes()].concat();
311
312 Self::from_be_bytes(bytes.try_into().unwrap())
313 }
314}
315
316impl From<Uint128> for Uint512 {
317 fn from(val: Uint128) -> Self {
318 val.u128().into()
319 }
320}
321
322impl From<Uint64> for Uint512 {
323 fn from(val: Uint64) -> Self {
324 val.u64().into()
325 }
326}
327
328impl From<u128> for Uint512 {
329 fn from(val: u128) -> Self {
330 Uint512(val.into())
331 }
332}
333
334impl From<u64> for Uint512 {
335 fn from(val: u64) -> Self {
336 Uint512(val.into())
337 }
338}
339
340impl From<u32> for Uint512 {
341 fn from(val: u32) -> Self {
342 Uint512(val.into())
343 }
344}
345
346impl From<u16> for Uint512 {
347 fn from(val: u16) -> Self {
348 Uint512(val.into())
349 }
350}
351
352impl From<u8> for Uint512 {
353 fn from(val: u8) -> Self {
354 Uint512(val.into())
355 }
356}
357
358impl TryFrom<Uint512> for Uint256 {
359 type Error = ConversionOverflowError;
360
361 fn try_from(value: Uint512) -> Result<Self, Self::Error> {
362 let bytes = value.to_be_bytes();
363 let (first_bytes, last_bytes) = bytes.split_at(32);
364
365 if first_bytes != [0u8; 32] {
366 return Err(ConversionOverflowError::new(
367 "Uint512",
368 "Uint256",
369 value.to_string(),
370 ));
371 }
372
373 Ok(Self::from_be_bytes(last_bytes.try_into().unwrap()))
374 }
375}
376
377impl TryFrom<Uint512> for Uint128 {
378 type Error = ConversionOverflowError;
379
380 fn try_from(value: Uint512) -> Result<Self, Self::Error> {
381 Ok(Uint128::new(value.0.try_into().map_err(|_| {
382 ConversionOverflowError::new("Uint512", "Uint128", value.to_string())
383 })?))
384 }
385}
386
387impl TryFrom<&str> for Uint512 {
388 type Error = StdError;
389
390 fn try_from(val: &str) -> Result<Self, Self::Error> {
391 Self::from_str(val)
392 }
393}
394
395impl FromStr for Uint512 {
396 type Err = StdError;
397
398 fn from_str(s: &str) -> Result<Self, Self::Err> {
399 match U512::from_dec_str(s) {
400 Ok(u) => Ok(Self(u)),
401 Err(e) => Err(StdError::generic_err(format!("Parsing u512: {}", e))),
402 }
403 }
404}
405
406impl From<Uint512> for String {
407 fn from(original: Uint512) -> Self {
408 original.to_string()
409 }
410}
411
412impl fmt::Display for Uint512 {
413 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
414 let unpadded = self.0.to_string();
417
418 f.pad_integral(true, "", &unpadded)
419 }
420}
421
422impl Add<Uint512> for Uint512 {
423 type Output = Self;
424
425 fn add(self, rhs: Self) -> Self {
426 Uint512(self.0.checked_add(rhs.0).unwrap())
427 }
428}
429
430impl<'a> Add<&'a Uint512> for Uint512 {
431 type Output = Self;
432
433 fn add(self, rhs: &'a Uint512) -> Self {
434 Uint512(self.0.checked_add(rhs.0).unwrap())
435 }
436}
437
438impl Sub<Uint512> for Uint512 {
439 type Output = Self;
440
441 fn sub(self, rhs: Self) -> Self {
442 Uint512(self.0.checked_sub(rhs.0).unwrap())
443 }
444}
445forward_ref_binop!(impl Sub, sub for Uint512, Uint512);
446
447impl SubAssign<Uint512> for Uint512 {
448 fn sub_assign(&mut self, rhs: Uint512) {
449 self.0 = self.0.checked_sub(rhs.0).unwrap();
450 }
451}
452forward_ref_op_assign!(impl SubAssign, sub_assign for Uint512, Uint512);
453
454impl Div<Uint512> for Uint512 {
455 type Output = Self;
456
457 fn div(self, rhs: Self) -> Self::Output {
458 Self(self.0.checked_div(rhs.0).unwrap())
459 }
460}
461
462impl<'a> Div<&'a Uint512> for Uint512 {
463 type Output = Self;
464
465 fn div(self, rhs: &'a Uint512) -> Self::Output {
466 Self(self.0.checked_div(rhs.0).unwrap())
467 }
468}
469
470impl Rem for Uint512 {
471 type Output = Self;
472
473 #[inline]
477 fn rem(self, rhs: Self) -> Self {
478 Self(self.0.rem(rhs.0))
479 }
480}
481forward_ref_binop!(impl Rem, rem for Uint512, Uint512);
482
483impl RemAssign<Uint512> for Uint512 {
484 fn rem_assign(&mut self, rhs: Uint512) {
485 *self = *self % rhs;
486 }
487}
488forward_ref_op_assign!(impl RemAssign, rem_assign for Uint512, Uint512);
489
490impl Mul<Uint512> for Uint512 {
491 type Output = Self;
492
493 fn mul(self, rhs: Self) -> Self::Output {
494 Self(self.0.checked_mul(rhs.0).unwrap())
495 }
496}
497forward_ref_binop!(impl Mul, mul for Uint512, Uint512);
498
499impl MulAssign<Uint512> for Uint512 {
500 fn mul_assign(&mut self, rhs: Self) {
501 self.0 = self.0.checked_mul(rhs.0).unwrap();
502 }
503}
504forward_ref_op_assign!(impl MulAssign, mul_assign for Uint512, Uint512);
505
506impl Shr<u32> for Uint512 {
507 type Output = Self;
508
509 fn shr(self, rhs: u32) -> Self::Output {
510 self.checked_shr(rhs).unwrap_or_else(|_| {
511 panic!(
512 "right shift error: {} is larger or equal than the number of bits in Uint512",
513 rhs,
514 )
515 })
516 }
517}
518
519impl<'a> Shr<&'a u32> for Uint512 {
520 type Output = Self;
521
522 fn shr(self, rhs: &'a u32) -> Self::Output {
523 Shr::<u32>::shr(self, *rhs)
524 }
525}
526
527impl AddAssign<Uint512> for Uint512 {
528 fn add_assign(&mut self, rhs: Uint512) {
529 self.0 = self.0.checked_add(rhs.0).unwrap();
530 }
531}
532
533impl<'a> AddAssign<&'a Uint512> for Uint512 {
534 fn add_assign(&mut self, rhs: &'a Uint512) {
535 self.0 = self.0.checked_add(rhs.0).unwrap();
536 }
537}
538
539impl DivAssign<Uint512> for Uint512 {
540 fn div_assign(&mut self, rhs: Self) {
541 self.0 = self.0.checked_div(rhs.0).unwrap();
542 }
543}
544
545impl<'a> DivAssign<&'a Uint512> for Uint512 {
546 fn div_assign(&mut self, rhs: &'a Uint512) {
547 self.0 = self.0.checked_div(rhs.0).unwrap();
548 }
549}
550
551impl ShrAssign<u32> for Uint512 {
552 fn shr_assign(&mut self, rhs: u32) {
553 *self = Shr::<u32>::shr(*self, rhs);
554 }
555}
556
557impl<'a> ShrAssign<&'a u32> for Uint512 {
558 fn shr_assign(&mut self, rhs: &'a u32) {
559 *self = Shr::<u32>::shr(*self, *rhs);
560 }
561}
562
563impl Serialize for Uint512 {
564 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
566 where
567 S: ser::Serializer,
568 {
569 serializer.serialize_str(&self.to_string())
570 }
571}
572
573impl<'de> Deserialize<'de> for Uint512 {
574 fn deserialize<D>(deserializer: D) -> Result<Uint512, D::Error>
576 where
577 D: Deserializer<'de>,
578 {
579 deserializer.deserialize_str(Uint512Visitor)
580 }
581}
582
583struct Uint512Visitor;
584
585impl<'de> de::Visitor<'de> for Uint512Visitor {
586 type Value = Uint512;
587
588 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
589 formatter.write_str("string-encoded integer")
590 }
591
592 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
593 where
594 E: de::Error,
595 {
596 Uint512::try_from(v).map_err(|e| E::custom(format!("invalid Uint512 '{}' - {}", v, e)))
597 }
598}
599
600impl<A> std::iter::Sum<A> for Uint512
601where
602 Self: Add<A, Output = Self>,
603{
604 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
605 iter.fold(Self::zero(), Add::add)
606 }
607}
608
609impl PartialEq<&Uint512> for Uint512 {
610 fn eq(&self, rhs: &&Uint512) -> bool {
611 self == *rhs
612 }
613}
614
615impl PartialEq<Uint512> for &Uint512 {
616 fn eq(&self, rhs: &Uint512) -> bool {
617 *self == rhs
618 }
619}
620
621#[cfg(test)]
622mod tests {
623 use super::*;
624 use crate::{from_slice, to_vec};
625
626 #[test]
627 fn uint512_new_works() {
628 let num = Uint512::new([1; 64]);
629 let a: [u8; 64] = num.to_be_bytes();
630 assert_eq!(a, [1; 64]);
631
632 let be_bytes = [
633 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
634 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
635 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
636 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
637 ];
638 let num = Uint512::new(be_bytes);
639 let resulting_bytes: [u8; 64] = num.to_be_bytes();
640 assert_eq!(be_bytes, resulting_bytes);
641 }
642
643 #[test]
644 fn uint512_zero_works() {
645 let zero = Uint512::zero();
646 assert_eq!(
647 zero.to_be_bytes(),
648 [
649 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
650 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
651 0, 0, 0, 0, 0, 0, 0, 0
652 ]
653 );
654 }
655
656 #[test]
657 fn uin512_one_works() {
658 let one = Uint512::one();
659 assert_eq!(
660 one.to_be_bytes(),
661 [
662 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
663 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
664 0, 0, 0, 0, 0, 0, 0, 1
665 ]
666 );
667 }
668
669 #[test]
670 fn uint512_endianness() {
671 let be_bytes = [
672 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
673 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
674 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
675 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
676 ];
677 let le_bytes = [
678 3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
679 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
680 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
681 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
682 ];
683
684 let num1 = Uint512::new(be_bytes);
686 let num2 = Uint512::from_be_bytes(be_bytes);
687 let num3 = Uint512::from_le_bytes(le_bytes);
688 assert_eq!(num1, Uint512::from(65536u32 + 512 + 3));
689 assert_eq!(num1, num2);
690 assert_eq!(num1, num3);
691 }
692
693 #[test]
694 fn uint512_convert_from() {
695 let a = Uint512::from(5u128);
696 assert_eq!(a.0, U512::from(5));
697
698 let a = Uint512::from(5u64);
699 assert_eq!(a.0, U512::from(5));
700
701 let a = Uint512::from(5u32);
702 assert_eq!(a.0, U512::from(5));
703
704 let a = Uint512::from(5u16);
705 assert_eq!(a.0, U512::from(5));
706
707 let a = Uint512::from(5u8);
708 assert_eq!(a.0, U512::from(5));
709
710 let result = Uint512::try_from("34567");
711 assert_eq!(result.unwrap().0, U512::from_dec_str("34567").unwrap());
712
713 let result = Uint512::try_from("1.23");
714 assert!(result.is_err());
715 }
716
717 #[test]
718 fn uint512_convert_to_uint128() {
719 let source = Uint512::from(42u128);
720 let target = Uint128::try_from(source);
721 assert_eq!(target, Ok(Uint128::new(42u128)));
722
723 let source = Uint512::MAX;
724 let target = Uint128::try_from(source);
725 assert_eq!(
726 target,
727 Err(ConversionOverflowError::new(
728 "Uint512",
729 "Uint128",
730 Uint512::MAX.to_string()
731 ))
732 );
733 }
734
735 #[test]
736 fn uint512_from_uint256() {
737 assert_eq!(
738 Uint512::from_uint256(Uint256::from_str("123").unwrap()),
739 Uint512::from_str("123").unwrap()
740 );
741
742 assert_eq!(
743 Uint512::from_uint256(Uint256::from_str("9785746283745").unwrap()),
744 Uint512::from_str("9785746283745").unwrap()
745 );
746
747 assert_eq!(
748 Uint512::from_uint256(
749 Uint256::from_str(
750 "97857462837575757832978493758398593853985452378423874623874628736482736487236"
751 )
752 .unwrap()
753 ),
754 Uint512::from_str(
755 "97857462837575757832978493758398593853985452378423874623874628736482736487236"
756 )
757 .unwrap()
758 );
759 }
760
761 #[test]
762 fn uint512_implements_display() {
763 let a = Uint512::from(12345u32);
764 assert_eq!(format!("Embedded: {}", a), "Embedded: 12345");
765 assert_eq!(a.to_string(), "12345");
766
767 let a = Uint512::zero();
768 assert_eq!(format!("Embedded: {}", a), "Embedded: 0");
769 assert_eq!(a.to_string(), "0");
770 }
771
772 #[test]
773 fn uint512_display_padding_works() {
774 let a = Uint512::from(123u64);
775 assert_eq!(format!("Embedded: {:05}", a), "Embedded: 00123");
776 }
777
778 #[test]
779 fn uint512_to_be_bytes_works() {
780 assert_eq!(
781 Uint512::zero().to_be_bytes(),
782 [
783 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
784 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
785 0, 0, 0, 0, 0, 0, 0, 0,
786 ]
787 );
788 assert_eq!(
789 Uint512::MAX.to_be_bytes(),
790 [
791 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
792 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
793 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
794 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
795 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
796 ]
797 );
798 assert_eq!(
799 Uint512::from(1u128).to_be_bytes(),
800 [
801 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
802 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
803 0, 0, 0, 0, 0, 0, 0, 1
804 ]
805 );
806 assert_eq!(
808 Uint512::from(240282366920938463463374607431768124608u128).to_be_bytes(),
809 [
810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
811 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 196, 179, 87, 165,
812 121, 59, 133, 246, 117, 221, 191, 255, 254, 172, 192
813 ]
814 );
815 assert_eq!(
816 Uint512::from_be_bytes([
817 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
818 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134,
819 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8,
820 252, 96, 230, 187, 38, 29
821 ])
822 .to_be_bytes(),
823 [
824 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
825 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134,
826 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8,
827 252, 96, 230, 187, 38, 29
828 ]
829 );
830 }
831
832 #[test]
833 fn uint512_to_le_bytes_works() {
834 assert_eq!(
835 Uint512::zero().to_le_bytes(),
836 [
837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
839 0, 0, 0, 0, 0, 0, 0, 0
840 ]
841 );
842 assert_eq!(
843 Uint512::MAX.to_le_bytes(),
844 [
845 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
846 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
847 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
848 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
849 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
850 ]
851 );
852 assert_eq!(
853 Uint512::from(1u128).to_le_bytes(),
854 [
855 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
856 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
857 0, 0, 0, 0, 0, 0, 0, 0
858 ]
859 );
860 assert_eq!(
862 Uint512::from(240282366920938463463374607431768124608u128).to_le_bytes(),
863 [
864 192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180, 0, 0,
865 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
866 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
867 ]
868 );
869 assert_eq!(
870 Uint512::from_be_bytes([
871 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
872 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134,
873 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8,
874 252, 96, 230, 187, 38, 29
875 ])
876 .to_le_bytes(),
877 [
878 29, 38, 187, 230, 96, 252, 8, 99, 12, 47, 22, 13, 59, 44, 10, 64, 73, 154, 195,
879 166, 88, 14, 22, 85, 119, 238, 134, 208, 45, 106, 88, 218, 240, 150, 115, 200, 240,
880 2, 233, 42, 7, 192, 201, 211, 54, 65, 76, 87, 78, 67, 21, 33, 38, 0, 91, 58, 200,
881 123, 67, 87, 32, 23, 4, 17
882 ]
883 );
884 }
885
886 #[test]
887 fn uint512_is_zero_works() {
888 assert!(Uint512::zero().is_zero());
889 assert!(Uint512(U512::from(0)).is_zero());
890
891 assert!(!Uint512::from(1u32).is_zero());
892 assert!(!Uint512::from(123u32).is_zero());
893 }
894
895 #[test]
896 fn uint512_wrapping_methods() {
897 assert_eq!(
899 Uint512::from(2u32).wrapping_add(Uint512::from(2u32)),
900 Uint512::from(4u32)
901 ); assert_eq!(
903 Uint512::MAX.wrapping_add(Uint512::from(1u32)),
904 Uint512::from(0u32)
905 ); assert_eq!(
909 Uint512::from(7u32).wrapping_sub(Uint512::from(5u32)),
910 Uint512::from(2u32)
911 ); assert_eq!(
913 Uint512::from(0u32).wrapping_sub(Uint512::from(1u32)),
914 Uint512::MAX
915 ); assert_eq!(
919 Uint512::from(3u32).wrapping_mul(Uint512::from(2u32)),
920 Uint512::from(6u32)
921 ); assert_eq!(
923 Uint512::MAX.wrapping_mul(Uint512::from(2u32)),
924 Uint512::MAX - Uint512::one()
925 ); assert_eq!(Uint512::from(2u32).wrapping_pow(3), Uint512::from(8u32)); assert_eq!(Uint512::MAX.wrapping_pow(2), Uint512::from(1u32)); }
931
932 #[test]
933 fn uint512_json() {
934 let orig = Uint512::from(1234567890987654321u128);
935 let serialized = to_vec(&orig).unwrap();
936 assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
937 let parsed: Uint512 = from_slice(&serialized).unwrap();
938 assert_eq!(parsed, orig);
939 }
940
941 #[test]
942 fn uint512_compare() {
943 let a = Uint512::from(12345u32);
944 let b = Uint512::from(23456u32);
945
946 assert!(a < b);
947 assert!(b > a);
948 assert_eq!(a, Uint512::from(12345u32));
949 }
950
951 #[test]
952 #[allow(clippy::op_ref)]
953 fn uint512_math() {
954 let a = Uint512::from(12345u32);
955 let b = Uint512::from(23456u32);
956
957 assert_eq!(a + b, Uint512::from(35801u32));
959 assert_eq!(a + &b, Uint512::from(35801u32));
960
961 assert_eq!(b - a, Uint512::from(11111u32));
963 assert_eq!(b - &a, Uint512::from(11111u32));
964
965 let mut c = Uint512::from(300000u32);
967 c += b;
968 assert_eq!(c, Uint512::from(323456u32));
969 let mut d = Uint512::from(300000u32);
970 d += &b;
971 assert_eq!(d, Uint512::from(323456u32));
972
973 let mut c = Uint512::from(300000u32);
975 c -= b;
976 assert_eq!(c, Uint512::from(276544u32));
977 let mut d = Uint512::from(300000u32);
978 d -= &b;
979 assert_eq!(d, Uint512::from(276544u32));
980
981 let underflow_result = a.checked_sub(b);
983 let OverflowError {
984 operand1, operand2, ..
985 } = underflow_result.unwrap_err();
986 assert_eq!((operand1, operand2), (a.to_string(), b.to_string()));
987 }
988
989 #[test]
990 #[should_panic]
991 fn uint512_add_overflow_panics() {
992 let max = Uint512::new([255u8; 64]);
993 let _ = max + Uint512::from(12u32);
994 }
995
996 #[test]
997 #[allow(clippy::op_ref)]
998 fn uint512_sub_works() {
999 assert_eq!(
1000 Uint512::from(2u32) - Uint512::from(1u32),
1001 Uint512::from(1u32)
1002 );
1003 assert_eq!(
1004 Uint512::from(2u32) - Uint512::from(0u32),
1005 Uint512::from(2u32)
1006 );
1007 assert_eq!(
1008 Uint512::from(2u32) - Uint512::from(2u32),
1009 Uint512::from(0u32)
1010 );
1011
1012 let a = Uint512::from(10u32);
1014 let b = Uint512::from(3u32);
1015 let expected = Uint512::from(7u32);
1016 assert_eq!(a - b, expected);
1017 assert_eq!(a - &b, expected);
1018 assert_eq!(&a - b, expected);
1019 assert_eq!(&a - &b, expected);
1020 }
1021
1022 #[test]
1023 #[should_panic]
1024 fn uint512_sub_overflow_panics() {
1025 let _ = Uint512::from(1u32) - Uint512::from(2u32);
1026 }
1027
1028 #[test]
1029 fn uint512_sub_assign_works() {
1030 let mut a = Uint512::from(14u32);
1031 a -= Uint512::from(2u32);
1032 assert_eq!(a, Uint512::from(12u32));
1033
1034 let mut a = Uint512::from(10u32);
1036 let b = Uint512::from(3u32);
1037 let expected = Uint512::from(7u32);
1038 a -= &b;
1039 assert_eq!(a, expected);
1040 }
1041
1042 #[test]
1043 #[allow(clippy::op_ref)]
1044 fn uint512_mul_works() {
1045 assert_eq!(
1046 Uint512::from(2u32) * Uint512::from(3u32),
1047 Uint512::from(6u32)
1048 );
1049 assert_eq!(Uint512::from(2u32) * Uint512::zero(), Uint512::zero());
1050
1051 let a = Uint512::from(11u32);
1053 let b = Uint512::from(3u32);
1054 let expected = Uint512::from(33u32);
1055 assert_eq!(a * b, expected);
1056 assert_eq!(a * &b, expected);
1057 assert_eq!(&a * b, expected);
1058 assert_eq!(&a * &b, expected);
1059 }
1060
1061 #[test]
1062 fn uint512_mul_assign_works() {
1063 let mut a = Uint512::from(14u32);
1064 a *= Uint512::from(2u32);
1065 assert_eq!(a, Uint512::from(28u32));
1066
1067 let mut a = Uint512::from(10u32);
1069 let b = Uint512::from(3u32);
1070 a *= &b;
1071 assert_eq!(a, Uint512::from(30u32));
1072 }
1073
1074 #[test]
1075 fn uint512_pow_works() {
1076 assert_eq!(Uint512::from(2u32).pow(2), Uint512::from(4u32));
1077 assert_eq!(Uint512::from(2u32).pow(10), Uint512::from(1024u32));
1078 }
1079
1080 #[test]
1081 #[should_panic]
1082 fn uint512_pow_overflow_panics() {
1083 Uint512::MAX.pow(2u32);
1084 }
1085
1086 #[test]
1087 fn uint512_shr_works() {
1088 let original = Uint512::new([
1089 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1090 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1091 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1092 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8,
1093 ]);
1094
1095 let shifted = Uint512::new([
1096 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1097 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1098 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1099 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8,
1100 ]);
1101
1102 assert_eq!(original >> 2u32, shifted);
1103 }
1104
1105 #[test]
1106 #[should_panic]
1107 fn uint512_shr_overflow_panics() {
1108 let _ = Uint512::from(1u32) >> 512u32;
1109 }
1110
1111 #[test]
1112 fn sum_works() {
1113 let nums = vec![
1114 Uint512::from(17u32),
1115 Uint512::from(123u32),
1116 Uint512::from(540u32),
1117 Uint512::from(82u32),
1118 ];
1119 let expected = Uint512::from(762u32);
1120
1121 let sum_as_ref: Uint512 = nums.iter().sum();
1122 assert_eq!(expected, sum_as_ref);
1123
1124 let sum_as_owned: Uint512 = nums.into_iter().sum();
1125 assert_eq!(expected, sum_as_owned);
1126 }
1127
1128 #[test]
1129 fn uint512_methods() {
1130 assert!(matches!(
1132 Uint512::MAX.checked_add(Uint512::from(1u32)),
1133 Err(OverflowError { .. })
1134 ));
1135 assert_eq!(
1136 Uint512::from(1u32).checked_add(Uint512::from(1u32)),
1137 Ok(Uint512::from(2u32)),
1138 );
1139 assert!(matches!(
1140 Uint512::from(0u32).checked_sub(Uint512::from(1u32)),
1141 Err(OverflowError { .. })
1142 ));
1143 assert_eq!(
1144 Uint512::from(2u32).checked_sub(Uint512::from(1u32)),
1145 Ok(Uint512::from(1u32)),
1146 );
1147 assert!(matches!(
1148 Uint512::MAX.checked_mul(Uint512::from(2u32)),
1149 Err(OverflowError { .. })
1150 ));
1151 assert_eq!(
1152 Uint512::from(2u32).checked_mul(Uint512::from(2u32)),
1153 Ok(Uint512::from(4u32)),
1154 );
1155 assert!(matches!(
1156 Uint512::MAX.checked_pow(2u32),
1157 Err(OverflowError { .. })
1158 ));
1159 assert_eq!(
1160 Uint512::from(2u32).checked_pow(3u32),
1161 Ok(Uint512::from(8u32)),
1162 );
1163 assert!(matches!(
1164 Uint512::MAX.checked_div(Uint512::from(0u32)),
1165 Err(DivideByZeroError { .. })
1166 ));
1167 assert_eq!(
1168 Uint512::from(6u32).checked_div(Uint512::from(2u32)),
1169 Ok(Uint512::from(3u32)),
1170 );
1171 assert!(matches!(
1172 Uint512::MAX.checked_div_euclid(Uint512::from(0u32)),
1173 Err(DivideByZeroError { .. })
1174 ));
1175 assert_eq!(
1176 Uint512::from(6u32).checked_div_euclid(Uint512::from(2u32)),
1177 Ok(Uint512::from(3u32)),
1178 );
1179 assert_eq!(
1180 Uint512::from(7u32).checked_div_euclid(Uint512::from(2u32)),
1181 Ok(Uint512::from(3u32)),
1182 );
1183 assert!(matches!(
1184 Uint512::MAX.checked_rem(Uint512::from(0u32)),
1185 Err(DivideByZeroError { .. })
1186 ));
1187
1188 assert_eq!(
1190 Uint512::MAX.saturating_add(Uint512::from(1u32)),
1191 Uint512::MAX
1192 );
1193 assert_eq!(
1194 Uint512::from(0u32).saturating_sub(Uint512::from(1u32)),
1195 Uint512::from(0u32)
1196 );
1197 assert_eq!(
1198 Uint512::MAX.saturating_mul(Uint512::from(2u32)),
1199 Uint512::MAX
1200 );
1201 assert_eq!(
1202 Uint512::from(4u32).saturating_pow(2u32),
1203 Uint512::from(16u32)
1204 );
1205 assert_eq!(Uint512::MAX.saturating_pow(2u32), Uint512::MAX);
1206 }
1207
1208 #[test]
1209 #[allow(clippy::op_ref)]
1210 fn uint512_implements_rem() {
1211 let a = Uint512::from(10u32);
1212 assert_eq!(a % Uint512::from(10u32), Uint512::zero());
1213 assert_eq!(a % Uint512::from(2u32), Uint512::zero());
1214 assert_eq!(a % Uint512::from(1u32), Uint512::zero());
1215 assert_eq!(a % Uint512::from(3u32), Uint512::from(1u32));
1216 assert_eq!(a % Uint512::from(4u32), Uint512::from(2u32));
1217
1218 let a = Uint512::from(10u32);
1220 let b = Uint512::from(3u32);
1221 let expected = Uint512::from(1u32);
1222 assert_eq!(a % b, expected);
1223 assert_eq!(a % &b, expected);
1224 assert_eq!(&a % b, expected);
1225 assert_eq!(&a % &b, expected);
1226 }
1227
1228 #[test]
1229 #[should_panic(expected = "division by zero")]
1230 fn uint512_rem_panics_for_zero() {
1231 let _ = Uint512::from(10u32) % Uint512::zero();
1232 }
1233
1234 #[test]
1235 #[allow(clippy::op_ref)]
1236 fn uint512_rem_works() {
1237 assert_eq!(
1238 Uint512::from(12u32) % Uint512::from(10u32),
1239 Uint512::from(2u32)
1240 );
1241 assert_eq!(Uint512::from(50u32) % Uint512::from(5u32), Uint512::zero());
1242
1243 let a = Uint512::from(42u32);
1245 let b = Uint512::from(5u32);
1246 let expected = Uint512::from(2u32);
1247 assert_eq!(a % b, expected);
1248 assert_eq!(a % &b, expected);
1249 assert_eq!(&a % b, expected);
1250 assert_eq!(&a % &b, expected);
1251 }
1252
1253 #[test]
1254 fn uint512_rem_assign_works() {
1255 let mut a = Uint512::from(30u32);
1256 a %= Uint512::from(4u32);
1257 assert_eq!(a, Uint512::from(2u32));
1258
1259 let mut a = Uint512::from(25u32);
1261 let b = Uint512::from(6u32);
1262 a %= &b;
1263 assert_eq!(a, Uint512::from(1u32));
1264 }
1265
1266 #[test]
1267 fn uint512_abs_diff_works() {
1268 let a = Uint512::from(42u32);
1269 let b = Uint512::from(5u32);
1270 let expected = Uint512::from(37u32);
1271 assert_eq!(a.abs_diff(b), expected);
1272 assert_eq!(b.abs_diff(a), expected);
1273 }
1274
1275 #[test]
1276 fn uint512_partial_eq() {
1277 let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)]
1278 .into_iter()
1279 .map(|(lhs, rhs, expected): (u64, u64, bool)| {
1280 (Uint512::from(lhs), Uint512::from(rhs), expected)
1281 });
1282
1283 #[allow(clippy::op_ref)]
1284 for (lhs, rhs, expected) in test_cases {
1285 assert_eq!(lhs == rhs, expected);
1286 assert_eq!(&lhs == rhs, expected);
1287 assert_eq!(lhs == &rhs, expected);
1288 assert_eq!(&lhs == &rhs, expected);
1289 }
1290 }
1291}