defituna_client/math/
u256.rs1use crate::math::U256;
2use crate::TunaError as ErrorCode;
3use std::borrow::BorrowMut;
4use std::convert::TryInto;
5use std::mem::size_of;
6
7impl U256 {
8 pub fn try_into_u64(self) -> Result<u64, ErrorCode> {
9 self.try_into().map_err(|_| ErrorCode::TypeCastOverflow)
10 }
11
12 pub fn try_into_u128(self) -> Result<u128, ErrorCode> {
13 self.try_into().map_err(|_| ErrorCode::TypeCastOverflow)
14 }
15
16 pub fn from_le_bytes(bytes: [u8; 32]) -> Self {
17 U256::from_little_endian(&bytes)
18 }
19
20 pub fn to_le_bytes(self) -> [u8; 32] {
21 let mut buf: Vec<u8> = Vec::with_capacity(size_of::<Self>());
22 self.to_little_endian(buf.borrow_mut());
23
24 let mut bytes: [u8; 32] = [0u8; 32];
25 bytes.copy_from_slice(buf.as_slice());
26 bytes
27 }
28
29 pub fn checked_shl(self, shl: u32) -> Option<U256> {
30 if self == U256::zero() {
31 return Some(Self::zero());
32 }
33
34 if shl >= 256 {
35 return None;
36 }
37
38 let mask = ((U256::one() << shl) - 1) << (256 - shl);
39 if self & mask != U256::zero() {
40 return None;
41 }
42
43 Some(self << shl)
44 }
45}
46
47#[cfg(test)]
48mod test_u256 {
49 use super::*;
50 use std::ops::Shl;
51
52 #[test]
53 fn test_into_u128_ok() {
54 let a = U256::from(2653u128);
55 let b = U256::from(1232u128);
56 let sum = a + b;
57 let d: u128 = sum.try_into_u128().unwrap();
58 assert_eq!(d, 3885u128);
59 }
60
61 #[test]
62 fn test_into_u128_error() {
63 let a = U256::from(u128::MAX);
64 let b = U256::from(u128::MAX);
65 let sum = a + b;
66 let c: Result<u128, ErrorCode> = sum.try_into_u128();
67 assert!(c.is_err());
68 }
69
70 #[test]
71 fn test_as_u128_ok() {
72 let a = U256::from(2653u128);
73 let b = U256::from(1232u128);
74 let sum = a + b;
75 let d: u128 = sum.as_u128();
76 assert_eq!(d, 3885u128);
77 }
78
79 #[test]
80 #[should_panic(expected = "Integer overflow when casting to u128")]
81 fn test_as_u128_panic() {
82 let a = U256::from(u128::MAX);
83 let b = U256::from(u128::MAX);
84 let sum = a + b;
85 let _: u128 = sum.as_u128();
86 }
87
88 #[test]
89 fn test_into_u64_ok() {
90 let a = U256::from(2653u64);
91 let b = U256::from(1232u64);
92 let sum = a + b;
93 let d: u64 = sum.try_into_u64().unwrap();
94 assert_eq!(d, 3885u64);
95 }
96
97 #[test]
98 fn test_into_u64_error() {
99 let a = U256::from(u64::MAX);
100 let b = U256::from(u64::MAX);
101 let sum = a + b;
102 let c: Result<u64, ErrorCode> = sum.try_into_u64();
103 assert!(c.is_err());
104 }
105
106 #[test]
107 fn test_as_u64_ok() {
108 let a = U256::from(2653u64);
109 let b = U256::from(1232u64);
110 let sum = a + b;
111 let d: u64 = sum.as_u64();
112 assert_eq!(d, 3885u64);
113 }
114
115 #[test]
116 #[should_panic(expected = "Integer overflow when casting to u64")]
117 fn test_as_u64_panic() {
118 let a = U256::from(u64::MAX);
119 let b = U256::from(u64::MAX);
120 let sum = a + b;
121 let _: u64 = sum.as_u64(); }
123
124 #[test]
125 fn test_checked_shl() {
126 assert_eq!(U256::zero().checked_shl(256), Some(U256::zero()));
127 assert_eq!(U256::one().checked_shl(1), Some(U256::from(2)));
128 assert_eq!(U256::one().checked_shl(255), Some(U256::one().shl(255)));
129 assert_eq!(U256::one().checked_shl(256), None);
130 assert_eq!(U256::from(3).checked_shl(255), None);
131 assert_eq!(U256::from(4).checked_shl(254), None);
132 assert_eq!(U256::zero().checked_shl(256).unwrap(), U256::zero());
133 }
134}