1use core::{cmp::Ordering, convert::Infallible, fmt::Debug};
2
3use super::{
4 env::internal::{
5 DurationSmall, DurationVal, Env as _, I256Small, I256Val, TimepointSmall, TimepointVal,
6 U256Small, U256Val,
7 },
8 Bytes, ConversionError, Env, TryFromVal, TryIntoVal, Val,
9};
10
11#[cfg(not(target_family = "wasm"))]
12use crate::env::internal::xdr::ScVal;
13use crate::unwrap::{UnwrapInfallible, UnwrapOptimized};
14
15macro_rules! impl_num_wrapping_val_type {
16 ($wrapper:ident, $val:ty, $small:ty) => {
17 impl Debug for $wrapper {
18 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19 write!(f, "{:?}", self.val.as_val())
21 }
22 }
23
24 impl Eq for $wrapper {}
25
26 impl PartialEq for $wrapper {
27 fn eq(&self, other: &Self) -> bool {
28 self.partial_cmp(other) == Some(Ordering::Equal)
29 }
30 }
31
32 impl PartialOrd for $wrapper {
33 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
34 Some(Ord::cmp(self, other))
35 }
36 }
37
38 impl Ord for $wrapper {
39 fn cmp(&self, other: &Self) -> Ordering {
40 let self_raw = self.val.to_val();
41 let other_raw = other.val.to_val();
42
43 match (<$small>::try_from(self_raw), <$small>::try_from(other_raw)) {
44 (Ok(self_num), Ok(other_num)) => self_num.cmp(&other_num),
46 _ => {
49 #[cfg(not(target_family = "wasm"))]
50 if !self.env.is_same_env(&other.env) {
51 return ScVal::from(self).cmp(&ScVal::from(other));
52 }
53 let v = self.env.obj_cmp(self_raw, other_raw).unwrap_infallible();
54 v.cmp(&0)
55 }
56 }
57 }
58 }
59
60 impl From<$wrapper> for $val {
61 #[inline(always)]
62 fn from(v: $wrapper) -> Self {
63 v.val
64 }
65 }
66
67 impl From<&$wrapper> for $val {
68 #[inline(always)]
69 fn from(v: &$wrapper) -> Self {
70 v.val
71 }
72 }
73
74 impl From<&$wrapper> for $wrapper {
75 #[inline(always)]
76 fn from(v: &$wrapper) -> Self {
77 v.clone()
78 }
79 }
80
81 impl TryFromVal<Env, $val> for $wrapper {
82 type Error = Infallible;
83
84 fn try_from_val(env: &Env, val: &$val) -> Result<Self, Self::Error> {
85 Ok(unsafe { $wrapper::unchecked_new(env.clone(), *val) })
86 }
87 }
88
89 impl TryFromVal<Env, Val> for $wrapper {
90 type Error = ConversionError;
91
92 fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
93 Ok(<$val>::try_from_val(env, val)?
94 .try_into_val(env)
95 .unwrap_infallible())
96 }
97 }
98
99 impl TryFromVal<Env, $wrapper> for Val {
100 type Error = ConversionError;
101
102 fn try_from_val(_env: &Env, v: &$wrapper) -> Result<Self, Self::Error> {
103 Ok(v.to_val())
104 }
105 }
106
107 impl TryFromVal<Env, &$wrapper> for Val {
108 type Error = ConversionError;
109
110 fn try_from_val(_env: &Env, v: &&$wrapper) -> Result<Self, Self::Error> {
111 Ok(v.to_val())
112 }
113 }
114
115 #[cfg(not(target_family = "wasm"))]
116 impl From<&$wrapper> for ScVal {
117 fn from(v: &$wrapper) -> Self {
118 if let Ok(ss) = <$small>::try_from(v.val) {
124 ScVal::try_from(ss).unwrap()
125 } else {
126 ScVal::try_from_val(&v.env, &v.to_val()).unwrap()
127 }
128 }
129 }
130
131 #[cfg(not(target_family = "wasm"))]
132 impl From<$wrapper> for ScVal {
133 fn from(v: $wrapper) -> Self {
134 (&v).into()
135 }
136 }
137
138 #[cfg(not(target_family = "wasm"))]
139 impl TryFromVal<Env, ScVal> for $wrapper {
140 type Error = ConversionError;
141 fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
142 Ok(<$val>::try_from_val(env, &Val::try_from_val(env, val)?)?
143 .try_into_val(env)
144 .unwrap_infallible())
145 }
146 }
147
148 impl $wrapper {
149 #[inline(always)]
150 pub(crate) unsafe fn unchecked_new(env: Env, val: $val) -> Self {
151 Self { env, val }
152 }
153
154 #[inline(always)]
158 pub(crate) unsafe fn unchecked_from_val(env: Env, val: Val) -> Self {
159 Self {
160 env,
161 val: <$val>::try_from(val).unwrap_optimized(),
162 }
163 }
164
165 #[inline(always)]
166 pub fn env(&self) -> &Env {
167 &self.env
168 }
169
170 pub fn as_val(&self) -> &Val {
171 self.val.as_val()
172 }
173
174 pub fn to_val(&self) -> Val {
175 self.val.to_val()
176 }
177
178 pub fn to_val_type(&self) -> $val {
179 self.val
180 }
181 }
182 };
183}
184
185#[derive(Clone)]
198pub struct U256 {
199 env: Env,
200 val: U256Val,
201}
202
203impl_num_wrapping_val_type!(U256, U256Val, U256Small);
204
205impl U256 {
206 pub const BITS: u32 = 256;
207
208 pub fn min_value(env: &Env) -> Self {
210 Self::from_u32(env, 0)
211 }
212
213 pub fn max_value(env: &Env) -> Self {
215 Self::from_parts(env, u64::MAX, u64::MAX, u64::MAX, u64::MAX)
216 }
217
218 fn is_zero(&self) -> bool {
219 *self == U256::from_u32(&self.env, 0)
220 }
221
222 pub fn from_u32(env: &Env, u: u32) -> Self {
223 U256 {
224 env: env.clone(),
225 val: U256Val::from_u32(u),
226 }
227 }
228
229 pub fn from_u128(env: &Env, u: u128) -> Self {
230 let lo: Bytes = Bytes::from_array(env, &u.to_be_bytes());
231 let mut bytes: Bytes = Bytes::from_array(env, &[0u8; 16]);
232 bytes.append(&lo);
233 Self::from_be_bytes(env, &bytes)
234 }
235
236 pub fn from_parts(env: &Env, hi_hi: u64, hi_lo: u64, lo_hi: u64, lo_lo: u64) -> Self {
237 let obj = env
238 .obj_from_u256_pieces(hi_hi, hi_lo, lo_hi, lo_lo)
239 .unwrap_infallible();
240 U256 {
241 env: env.clone(),
242 val: obj.into(),
243 }
244 }
245
246 pub fn from_be_bytes(env: &Env, bytes: &Bytes) -> Self {
247 let val = env
248 .u256_val_from_be_bytes(bytes.to_object())
249 .unwrap_infallible();
250 U256 {
251 env: env.clone(),
252 val,
253 }
254 }
255
256 pub fn to_u128(&self) -> Option<u128> {
257 let be_bytes = self.to_be_bytes();
258 let be_bytes_hi: [u8; 16] = be_bytes.slice(0..16).try_into().unwrap();
259 let be_bytes_lo: [u8; 16] = be_bytes.slice(16..32).try_into().unwrap();
260 if u128::from_be_bytes(be_bytes_hi) == 0 {
261 Some(u128::from_be_bytes(be_bytes_lo))
262 } else {
263 None
264 }
265 }
266
267 pub fn to_be_bytes(&self) -> Bytes {
268 let obj = self
269 .env
270 .u256_val_to_be_bytes(self.to_val_type())
271 .unwrap_infallible();
272 unsafe { Bytes::unchecked_new(self.env.clone(), obj) }
273 }
274
275 pub fn add(&self, other: &U256) -> U256 {
276 let val = self.env.u256_add(self.val, other.val).unwrap_infallible();
277 U256 {
278 env: self.env.clone(),
279 val,
280 }
281 }
282
283 pub fn sub(&self, other: &U256) -> U256 {
284 let val = self.env.u256_sub(self.val, other.val).unwrap_infallible();
285 U256 {
286 env: self.env.clone(),
287 val,
288 }
289 }
290
291 pub fn mul(&self, other: &U256) -> U256 {
292 let val = self.env.u256_mul(self.val, other.val).unwrap_infallible();
293 U256 {
294 env: self.env.clone(),
295 val,
296 }
297 }
298
299 pub fn div(&self, other: &U256) -> U256 {
300 let val = self.env.u256_div(self.val, other.val).unwrap_infallible();
301 U256 {
302 env: self.env.clone(),
303 val,
304 }
305 }
306
307 pub fn rem_euclid(&self, other: &U256) -> U256 {
308 let val = self
309 .env
310 .u256_rem_euclid(self.val, other.val)
311 .unwrap_infallible();
312 U256 {
313 env: self.env.clone(),
314 val,
315 }
316 }
317
318 pub fn pow(&self, pow: u32) -> U256 {
319 let val = self.env.u256_pow(self.val, pow.into()).unwrap_infallible();
320 U256 {
321 env: self.env.clone(),
322 val,
323 }
324 }
325
326 pub fn shl(&self, bits: u32) -> U256 {
327 let val = self.env.u256_shl(self.val, bits.into()).unwrap_infallible();
328 U256 {
329 env: self.env.clone(),
330 val,
331 }
332 }
333
334 pub fn shr(&self, bits: u32) -> U256 {
335 let val = self.env.u256_shr(self.val, bits.into()).unwrap_infallible();
336 U256 {
337 env: self.env.clone(),
338 val,
339 }
340 }
341
342 pub fn checked_add(&self, other: &U256) -> Option<U256> {
344 let val = self
345 .env
346 .u256_checked_add(self.val, other.val)
347 .unwrap_infallible();
348 if val.is_void() {
349 None
350 } else {
351 Some(unsafe { U256::unchecked_from_val(self.env.clone(), val) })
352 }
353 }
354
355 pub fn checked_sub(&self, other: &U256) -> Option<U256> {
357 let val = self
358 .env
359 .u256_checked_sub(self.val, other.val)
360 .unwrap_infallible();
361 if val.is_void() {
362 None
363 } else {
364 Some(unsafe { U256::unchecked_from_val(self.env.clone(), val) })
365 }
366 }
367
368 pub fn checked_mul(&self, other: &U256) -> Option<U256> {
370 let val = self
371 .env
372 .u256_checked_mul(self.val, other.val)
373 .unwrap_infallible();
374 if val.is_void() {
375 None
376 } else {
377 Some(unsafe { U256::unchecked_from_val(self.env.clone(), val) })
378 }
379 }
380
381 pub fn checked_pow(&self, pow: u32) -> Option<U256> {
383 let val = self
384 .env
385 .u256_checked_pow(self.val, pow.into())
386 .unwrap_infallible();
387 if val.is_void() {
388 None
389 } else {
390 Some(unsafe { U256::unchecked_from_val(self.env.clone(), val) })
391 }
392 }
393
394 pub fn checked_div(&self, other: &U256) -> Option<U256> {
396 if other.is_zero() {
397 return None;
398 }
399 Some(self.div(other))
400 }
401
402 pub fn checked_rem_euclid(&self, other: &U256) -> Option<U256> {
404 if other.is_zero() {
405 return None;
406 }
407 Some(self.rem_euclid(other))
408 }
409
410 pub fn checked_shl(&self, bits: u32) -> Option<U256> {
412 if bits >= Self::BITS {
413 return None;
414 }
415 Some(self.shl(bits))
416 }
417
418 pub fn checked_shr(&self, bits: u32) -> Option<U256> {
420 if bits >= Self::BITS {
421 return None;
422 }
423 Some(self.shr(bits))
424 }
425}
426
427#[derive(Clone)]
441pub struct I256 {
442 env: Env,
443 val: I256Val,
444}
445
446impl_num_wrapping_val_type!(I256, I256Val, I256Small);
447
448impl I256 {
449 pub const BITS: u32 = 256;
450
451 pub fn min_value(env: &Env) -> Self {
453 Self::from_parts(env, i64::MIN, 0, 0, 0)
454 }
455
456 pub fn max_value(env: &Env) -> Self {
458 Self::from_parts(env, i64::MAX, u64::MAX, u64::MAX, u64::MAX)
459 }
460
461 fn is_zero(&self) -> bool {
462 *self == I256::from_i32(&self.env, 0)
463 }
464
465 fn is_neg_one(&self) -> bool {
466 *self == I256::from_i32(&self.env, -1)
467 }
468
469 pub fn from_i32(env: &Env, i: i32) -> Self {
470 I256 {
471 env: env.clone(),
472 val: I256Val::from_i32(i),
473 }
474 }
475
476 pub fn from_i128(env: &Env, i: i128) -> Self {
477 let lo: Bytes = Bytes::from_array(env, &i.to_be_bytes());
478 if i < 0 {
479 let mut i256_bytes: Bytes = Bytes::from_array(env, &[255_u8; 16]);
480 i256_bytes.append(&lo);
481 Self::from_be_bytes(env, &i256_bytes)
482 } else {
483 let mut i256_bytes: Bytes = Bytes::from_array(env, &[0_u8; 16]);
484 i256_bytes.append(&lo);
485 Self::from_be_bytes(env, &i256_bytes)
486 }
487 }
488
489 pub fn from_parts(env: &Env, hi_hi: i64, hi_lo: u64, lo_hi: u64, lo_lo: u64) -> Self {
490 let obj = env
491 .obj_from_i256_pieces(hi_hi, hi_lo, lo_hi, lo_lo)
492 .unwrap_infallible();
493 I256 {
494 env: env.clone(),
495 val: obj.into(),
496 }
497 }
498
499 pub fn from_be_bytes(env: &Env, bytes: &Bytes) -> Self {
500 let val = env
501 .i256_val_from_be_bytes(bytes.to_object())
502 .unwrap_infallible();
503 I256 {
504 env: env.clone(),
505 val,
506 }
507 }
508
509 pub fn to_i128(&self) -> Option<i128> {
510 let be_bytes = self.to_be_bytes();
511 let be_bytes_hi: [u8; 16] = be_bytes.slice(0..16).try_into().unwrap();
512 let be_bytes_lo: [u8; 16] = be_bytes.slice(16..32).try_into().unwrap();
513 let i128_hi = i128::from_be_bytes(be_bytes_hi);
514 let i128_lo = i128::from_be_bytes(be_bytes_lo);
515 if (i128_hi == 0 && i128_lo >= 0) || (i128_hi == -1 && i128_lo < 0) {
516 Some(i128_lo)
517 } else {
518 None
519 }
520 }
521
522 pub fn to_be_bytes(&self) -> Bytes {
523 let obj = self
524 .env
525 .i256_val_to_be_bytes(self.to_val_type())
526 .unwrap_infallible();
527 unsafe { Bytes::unchecked_new(self.env.clone(), obj) }
528 }
529
530 pub fn add(&self, other: &I256) -> I256 {
531 let val = self.env.i256_add(self.val, other.val).unwrap_infallible();
532 I256 {
533 env: self.env.clone(),
534 val,
535 }
536 }
537
538 pub fn sub(&self, other: &I256) -> I256 {
539 let val = self.env.i256_sub(self.val, other.val).unwrap_infallible();
540 I256 {
541 env: self.env.clone(),
542 val,
543 }
544 }
545
546 pub fn mul(&self, other: &I256) -> I256 {
547 let val = self.env.i256_mul(self.val, other.val).unwrap_infallible();
548 I256 {
549 env: self.env.clone(),
550 val,
551 }
552 }
553
554 pub fn div(&self, other: &I256) -> I256 {
555 let val = self.env.i256_div(self.val, other.val).unwrap_infallible();
556 I256 {
557 env: self.env.clone(),
558 val,
559 }
560 }
561
562 pub fn rem_euclid(&self, other: &I256) -> I256 {
563 let val = self
564 .env
565 .i256_rem_euclid(self.val, other.val)
566 .unwrap_infallible();
567 I256 {
568 env: self.env.clone(),
569 val,
570 }
571 }
572
573 pub fn pow(&self, pow: u32) -> I256 {
574 let val = self.env.i256_pow(self.val, pow.into()).unwrap_infallible();
575 I256 {
576 env: self.env.clone(),
577 val,
578 }
579 }
580
581 pub fn shl(&self, bits: u32) -> I256 {
582 let val = self.env.i256_shl(self.val, bits.into()).unwrap_infallible();
583 I256 {
584 env: self.env.clone(),
585 val,
586 }
587 }
588
589 pub fn shr(&self, bits: u32) -> I256 {
590 let val = self.env.i256_shr(self.val, bits.into()).unwrap_infallible();
591 I256 {
592 env: self.env.clone(),
593 val,
594 }
595 }
596
597 pub fn checked_add(&self, other: &I256) -> Option<I256> {
599 let val = self
600 .env
601 .i256_checked_add(self.val, other.val)
602 .unwrap_infallible();
603 if val.is_void() {
604 None
605 } else {
606 Some(unsafe { I256::unchecked_from_val(self.env.clone(), val) })
607 }
608 }
609
610 pub fn checked_sub(&self, other: &I256) -> Option<I256> {
612 let val = self
613 .env
614 .i256_checked_sub(self.val, other.val)
615 .unwrap_infallible();
616 if val.is_void() {
617 None
618 } else {
619 Some(unsafe { I256::unchecked_from_val(self.env.clone(), val) })
620 }
621 }
622
623 pub fn checked_mul(&self, other: &I256) -> Option<I256> {
625 let val = self
626 .env
627 .i256_checked_mul(self.val, other.val)
628 .unwrap_infallible();
629 if val.is_void() {
630 None
631 } else {
632 Some(unsafe { I256::unchecked_from_val(self.env.clone(), val) })
633 }
634 }
635
636 pub fn checked_pow(&self, pow: u32) -> Option<I256> {
638 let val = self
639 .env
640 .i256_checked_pow(self.val, pow.into())
641 .unwrap_infallible();
642 if val.is_void() {
643 None
644 } else {
645 Some(unsafe { I256::unchecked_from_val(self.env.clone(), val) })
646 }
647 }
648
649 fn is_div_overflow(&self, other: &I256) -> bool {
652 if other.is_zero() {
653 return true;
654 }
655 if other.is_neg_one() {
656 let min = I256::min_value(&self.env);
657 if *self == min {
658 return true;
659 }
660 }
661 false
662 }
663
664 pub fn checked_div(&self, other: &I256) -> Option<I256> {
667 if self.is_div_overflow(other) {
668 return None;
669 }
670 Some(self.div(other))
671 }
672
673 pub fn checked_rem_euclid(&self, other: &I256) -> Option<I256> {
677 if self.is_div_overflow(other) {
678 return None;
679 }
680 Some(self.rem_euclid(other))
681 }
682
683 pub fn checked_shl(&self, bits: u32) -> Option<I256> {
685 if bits >= Self::BITS {
686 return None;
687 }
688 Some(self.shl(bits))
689 }
690
691 pub fn checked_shr(&self, bits: u32) -> Option<I256> {
693 if bits >= Self::BITS {
694 return None;
695 }
696 Some(self.shr(bits))
697 }
698}
699
700#[doc = "Timepoint holds a 64-bit unsigned integer."]
701#[derive(Clone)]
702pub struct Timepoint {
703 env: Env,
704 val: TimepointVal,
705}
706
707impl_num_wrapping_val_type!(Timepoint, TimepointVal, TimepointSmall);
708
709impl Timepoint {
710 pub fn from_unix(env: &Env, seconds: u64) -> Timepoint {
713 let val = TimepointVal::try_from_val(env, &seconds).unwrap_optimized();
714 Timepoint {
715 env: env.clone(),
716 val,
717 }
718 }
719
720 pub fn to_unix(&self) -> u64 {
723 u64::try_from_val(self.env(), &self.to_val_type()).unwrap_optimized()
724 }
725}
726
727#[doc = "Duration holds a 64-bit unsigned integer."]
728#[derive(Clone)]
729pub struct Duration {
730 env: Env,
731 val: DurationVal,
732}
733
734impl_num_wrapping_val_type!(Duration, DurationVal, DurationSmall);
735
736impl Duration {
737 pub fn from_seconds(env: &Env, seconds: u64) -> Duration {
739 let val = DurationVal::try_from_val(env, &seconds).unwrap_optimized();
740 Duration {
741 env: env.clone(),
742 val,
743 }
744 }
745
746 pub fn to_seconds(&self) -> u64 {
748 u64::try_from_val(self.env(), &self.to_val_type()).unwrap_optimized()
749 }
750}
751
752#[cfg(test)]
753mod test {
754 use super::*;
755
756 #[test]
757 fn test_u256_roundtrip() {
758 let env = Env::default();
759
760 let u1 = U256::from_u32(&env, 12345);
761 let bytes = u1.to_be_bytes();
762 let u2 = U256::from_be_bytes(&env, &bytes);
763 assert_eq!(u1, u2);
764 }
765
766 #[test]
767 fn test_u256_u128_conversion() {
768 let env = Env::default();
769
770 let start = u128::MAX / 7;
772 let from = U256::from_u128(&env, start);
773 let end = from.to_u128().unwrap();
774 assert_eq!(start, end);
775
776 let over_u128 = from.mul(&U256::from_u32(&env, 8));
777 let failure = over_u128.to_u128();
778 assert_eq!(failure, None);
779
780 let start = 0_u128;
782 let from = U256::from_u128(&env, start);
783 let end = from.to_u128().unwrap();
784 assert_eq!(start, end);
785 }
786
787 #[test]
788 fn test_i256_roundtrip() {
789 let env = Env::default();
790
791 let i1 = I256::from_i32(&env, -12345);
792 let bytes = i1.to_be_bytes();
793 let i2 = I256::from_be_bytes(&env, &bytes);
794 assert_eq!(i1, i2);
795 }
796
797 #[test]
798 fn test_i256_i128_conversion() {
799 let env = Env::default();
800
801 let start = i128::MAX / 7;
803 let from = I256::from_i128(&env, start);
804 let end = from.to_i128().unwrap();
805 assert_eq!(start, end);
806
807 let over_i128 = from.mul(&I256::from_i32(&env, 8));
808 let failure = over_i128.to_i128();
809 assert_eq!(failure, None);
810
811 let start = i128::MIN / 7;
813 let from = I256::from_i128(&env, start);
814 let end = from.to_i128().unwrap();
815 assert_eq!(start, end);
816
817 let over_i128 = from.mul(&I256::from_i32(&env, 8));
818 let failure = over_i128.to_i128();
819 assert_eq!(failure, None);
820
821 let start = 0_i128;
823 let from = I256::from_i128(&env, start);
824 let end = from.to_i128().unwrap();
825 assert_eq!(start, end);
826 }
827
828 #[test]
829 fn test_timepoint_roundtrip() {
830 let env = Env::default();
831
832 let tp = Timepoint::from_unix(&env, 123);
833 let u = tp.to_unix();
834 assert_eq!(u, 123);
835 }
836
837 #[test]
838 fn test_duration_roundtrip() {
839 let env = Env::default();
840
841 let tp = Duration::from_seconds(&env, 123);
842 let u = tp.to_seconds();
843 assert_eq!(u, 123);
844 }
845
846 #[test]
847 fn test_u256_arith() {
848 let env = Env::default();
849
850 let u1 = U256::from_u32(&env, 6);
851 let u2 = U256::from_u32(&env, 3);
852 assert_eq!(u1.add(&u2), U256::from_u32(&env, 9));
853 assert_eq!(u1.sub(&u2), U256::from_u32(&env, 3));
854 assert_eq!(u1.mul(&u2), U256::from_u32(&env, 18));
855 assert_eq!(u1.div(&u2), U256::from_u32(&env, 2));
856 assert_eq!(u1.pow(2), U256::from_u32(&env, 36));
857 assert_eq!(u1.shl(2), U256::from_u32(&env, 24));
858 assert_eq!(u1.shr(1), U256::from_u32(&env, 3));
859
860 let u3 = U256::from_u32(&env, 7);
861 let u4 = U256::from_u32(&env, 4);
862 assert_eq!(u3.rem_euclid(&u4), U256::from_u32(&env, 3));
863 }
864
865 #[test]
866 fn test_u256_min() {
867 let env = Env::default();
868
869 let min = U256::min_value(&env);
870 assert_eq!(min, U256::from_u32(&env, 0));
871
872 let one = U256::from_u32(&env, 1);
873 assert_eq!(min.checked_sub(&one), None);
874 assert!(min.checked_add(&one).is_some());
875 }
876
877 #[test]
878 fn test_u256_max() {
879 let env = Env::default();
880
881 let max = U256::max_value(&env);
882 assert_eq!(
883 max,
884 U256::from_parts(&env, u64::MAX, u64::MAX, u64::MAX, u64::MAX)
885 );
886
887 let u128_max = U256::from_u128(&env, u128::MAX);
888 assert!(max > u128_max);
889
890 let one = U256::from_u32(&env, 1);
891 assert_eq!(max.checked_add(&one), None);
892 assert!(max.checked_sub(&one).is_some());
893 }
894
895 #[test]
896 fn test_u256_checked_arith() {
897 let env = Env::default();
898
899 let u1 = U256::from_u32(&env, 6);
900 let u2 = U256::from_u32(&env, 3);
901 assert_eq!(u1.checked_add(&u2), Some(U256::from_u32(&env, 9)));
902 assert_eq!(u1.checked_sub(&u2), Some(U256::from_u32(&env, 3)));
903 assert_eq!(u1.checked_mul(&u2), Some(U256::from_u32(&env, 18)));
904 assert_eq!(u1.checked_div(&u2), Some(U256::from_u32(&env, 2)));
905 assert_eq!(u1.checked_pow(2), Some(U256::from_u32(&env, 36)));
906 assert_eq!(u1.checked_shl(2), Some(U256::from_u32(&env, 24)));
907 assert_eq!(u1.checked_shr(1), Some(U256::from_u32(&env, 3)));
908
909 let u3 = U256::from_u32(&env, 7);
910 let u4 = U256::from_u32(&env, 4);
911 assert_eq!(u3.checked_rem_euclid(&u4), Some(U256::from_u32(&env, 3)));
912 }
913
914 #[test]
915 fn test_u256_checked_arith_overflow() {
916 let env = Env::default();
917
918 let zero = U256::from_u32(&env, 0);
919 let one = U256::from_u32(&env, 1);
920 let two = U256::from_u32(&env, 2);
921 let max = U256::max_value(&env);
922 assert_eq!(max.checked_add(&one), None);
923 assert_eq!(zero.checked_sub(&one), None);
924 assert_eq!(max.checked_mul(&two), None);
925 assert_eq!(one.checked_div(&zero), None);
926 assert_eq!(max.checked_pow(2), None);
927 assert_eq!(one.checked_shl(256), None);
928 assert_eq!(one.checked_shr(256), None);
929 assert_eq!(one.checked_rem_euclid(&zero), None);
930
931 let zero_from_parts = U256::from_parts(&env, 0, 0, 0, 0);
932 let one_from_parts = U256::from_parts(&env, 0, 0, 0, 1);
933 assert_eq!(one.checked_div(&zero_from_parts), None);
934 assert_eq!(zero.checked_sub(&one_from_parts), None);
935 }
936
937 #[test]
938 fn test_u256_is_zero() {
939 let env = Env::default();
940
941 let zero = U256::from_u32(&env, 0);
942 let zero_from_parts = U256::from_parts(&env, 0, 0, 0, 0);
943 let non_zero = U256::from_u32(&env, 1);
944
945 assert!(zero.is_zero());
946 assert!(zero_from_parts.is_zero());
947 assert!(!non_zero.is_zero());
948 }
949
950 #[test]
951 fn test_i256_arith() {
952 let env = Env::default();
953
954 let i1 = I256::from_i32(&env, -6);
955 let i2 = I256::from_i32(&env, 3);
956 assert_eq!(i1.add(&i2), I256::from_i32(&env, -3));
957 assert_eq!(i1.sub(&i2), I256::from_i32(&env, -9));
958 assert_eq!(i1.mul(&i2), I256::from_i32(&env, -18));
959 assert_eq!(i1.div(&i2), I256::from_i32(&env, -2));
960 assert_eq!(i1.pow(2), I256::from_i32(&env, 36));
961 assert_eq!(i1.shl(2), I256::from_i32(&env, -24));
962 assert_eq!(i1.shr(1), I256::from_i32(&env, -3));
963
964 let u3 = I256::from_i32(&env, -7);
965 let u4 = I256::from_i32(&env, 4);
966 assert_eq!(u3.rem_euclid(&u4), I256::from_i32(&env, 1));
967 }
968
969 #[test]
970 fn test_i256_min() {
971 let env = Env::default();
972
973 let min = I256::min_value(&env);
974 assert_eq!(min, I256::from_parts(&env, i64::MIN, 0, 0, 0));
975
976 let i128_min = I256::from_i128(&env, i128::MIN);
977 assert!(min < i128_min);
978
979 let one = I256::from_i32(&env, 1);
980 assert_eq!(min.checked_sub(&one), None);
981 assert!(min.checked_add(&one).is_some());
982 }
983
984 #[test]
985 fn test_i256_max() {
986 let env = Env::default();
987
988 let max = I256::max_value(&env);
989 assert_eq!(
990 max,
991 I256::from_parts(&env, i64::MAX, u64::MAX, u64::MAX, u64::MAX)
992 );
993
994 let i128_max = I256::from_i128(&env, i128::MAX);
995 assert!(max > i128_max);
996
997 let one = I256::from_i32(&env, 1);
998 assert_eq!(max.checked_add(&one), None);
999 assert!(max.checked_sub(&one).is_some());
1000 }
1001
1002 #[test]
1003 fn test_i256_checked_arith() {
1004 let env = Env::default();
1005
1006 let i1 = I256::from_i32(&env, -6);
1007 let i2 = I256::from_i32(&env, 3);
1008 assert_eq!(i1.checked_add(&i2), Some(I256::from_i32(&env, -3)));
1009 assert_eq!(i1.checked_sub(&i2), Some(I256::from_i32(&env, -9)));
1010 assert_eq!(i1.checked_mul(&i2), Some(I256::from_i32(&env, -18)));
1011 assert_eq!(i1.checked_div(&i2), Some(I256::from_i32(&env, -2)));
1012 assert_eq!(i1.checked_pow(2), Some(I256::from_i32(&env, 36)));
1013 assert_eq!(i1.checked_shl(2), Some(I256::from_i32(&env, -24)));
1014 assert_eq!(i1.checked_shr(1), Some(I256::from_i32(&env, -3)));
1015
1016 let u3 = I256::from_i32(&env, -7);
1017 let u4 = I256::from_i32(&env, 4);
1018 assert_eq!(u3.checked_rem_euclid(&u4), Some(I256::from_i32(&env, 1)));
1019 }
1020
1021 #[test]
1022 fn test_i256_checked_arith_overflow() {
1023 let env = Env::default();
1024
1025 let zero = I256::from_i32(&env, 0);
1026 let one = I256::from_i32(&env, 1);
1027 let negative_one = I256::from_i32(&env, -1);
1028 let two = I256::from_i32(&env, 2);
1029 let max = I256::max_value(&env);
1030 let min = I256::min_value(&env);
1031 assert_eq!(max.checked_add(&one), None);
1032 assert_eq!(min.checked_sub(&one), None);
1033 assert_eq!(max.checked_mul(&two), None);
1034 assert_eq!(one.checked_div(&zero), None);
1035 assert_eq!(min.checked_div(&negative_one), None);
1036 assert_eq!(max.checked_pow(2), None);
1037 assert_eq!(one.checked_shl(256), None);
1038 assert_eq!(one.checked_shr(256), None);
1039 assert_eq!(one.checked_rem_euclid(&zero), None);
1040
1041 let zero_from_parts = I256::from_parts(&env, 0, 0, 0, 0);
1042 let one_from_parts = I256::from_parts(&env, 0, 0, 0, 1);
1043 assert_eq!(one.checked_div(&zero_from_parts), None);
1044 assert_eq!(min.checked_sub(&one_from_parts), None);
1045 }
1046
1047 #[test]
1048 fn test_i256_is_zero() {
1049 let env = Env::default();
1050
1051 let zero = I256::from_i32(&env, 0);
1052 let zero_from_parts = I256::from_parts(&env, 0, 0, 0, 0);
1053 let non_zero = I256::from_i32(&env, 1);
1054
1055 assert!(zero.is_zero());
1056 assert!(zero_from_parts.is_zero());
1057 assert!(!non_zero.is_zero());
1058 }
1059
1060 #[test]
1061 fn test_i256_is_neg_one() {
1062 let env = Env::default();
1063
1064 let negative_one = I256::from_i32(&env, -1);
1065 let negative_one_from_parts = I256::from_parts(&env, -1, u64::MAX, u64::MAX, u64::MAX);
1066 let negative_two = I256::from_i32(&env, -2);
1067
1068 assert!(negative_one.is_neg_one());
1069 assert!(negative_one_from_parts.is_neg_one());
1070 assert!(!negative_two.is_neg_one());
1071 }
1072
1073 #[test]
1074 fn test_i256_is_div_overflow() {
1075 let env = Env::default();
1076
1077 let zero = I256::from_i32(&env, 0);
1078 let negative_one = I256::from_i32(&env, -1);
1079 let min = I256::min_value(&env);
1080
1081 assert!(!zero.is_div_overflow(&negative_one));
1082
1083 assert!(negative_one.is_div_overflow(&zero));
1084 assert!(min.is_div_overflow(&negative_one));
1085 }
1086}