Skip to main content

neo_types/
integer.rs

1use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub};
2
3use num_bigint::BigInt;
4use num_traits::{One, ToPrimitive, Zero};
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8/// Neo N3 Integer type (arbitrary precision)
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub struct NeoInteger(BigInt);
12
13impl NeoInteger {
14    pub fn new<T: Into<BigInt>>(value: T) -> Self {
15        Self(value.into())
16    }
17
18    pub fn zero() -> Self {
19        Self(BigInt::zero())
20    }
21
22    pub fn one() -> Self {
23        Self(BigInt::one())
24    }
25
26    pub fn min_i32() -> Self {
27        Self(BigInt::from(i32::MIN))
28    }
29
30    pub fn max_i32() -> Self {
31        Self(BigInt::from(i32::MAX))
32    }
33
34    pub fn as_bigint(&self) -> &BigInt {
35        &self.0
36    }
37
38    /// Convert to i32, returning None if the value is out of range.
39    /// This is the safe alternative to `as_i32()` that doesn't panic.
40    pub fn try_as_i32(&self) -> Option<i32> {
41        self.0.to_i32()
42    }
43
44    /// Convert to u32, returning None if the value is out of range.
45    /// This is the safe alternative to `as_u32()` that doesn't panic.
46    pub fn try_as_u32(&self) -> Option<u32> {
47        self.0.to_u32()
48    }
49
50    /// Convert to i32, saturating at the boundaries if the value is out of range.
51    /// This never panics.
52    pub fn as_i32_saturating(&self) -> i32 {
53        self.0.to_i32().unwrap_or_else(|| {
54            if self.0.sign() == num_bigint::Sign::Minus {
55                i32::MIN
56            } else {
57                i32::MAX
58            }
59        })
60    }
61
62    /// Convert to u32, saturating at the boundaries if the value is out of range.
63    /// This never panics.
64    pub fn as_u32_saturating(&self) -> u32 {
65        self.0.to_u32().unwrap_or_else(|| {
66            if self.0.sign() == num_bigint::Sign::Minus {
67                0
68            } else {
69                u32::MAX
70            }
71        })
72    }
73
74    /// Convert to i32.
75    ///
76    /// # Panics
77    /// Panics if the value is outside the i32 range. Use `try_as_i32()` for a safe alternative.
78    #[deprecated(
79        since = "0.4.1",
80        note = "Use try_as_i32() or as_i32_saturating() instead to avoid panics"
81    )]
82    pub fn as_i32(&self) -> i32 {
83        self.0.to_i32().expect("NeoInteger value exceeds i32 range")
84    }
85
86    /// Convert to u32.
87    ///
88    /// # Panics
89    /// Panics if the value is outside the u32 range. Use `try_as_u32()` for a safe alternative.
90    #[deprecated(
91        since = "0.4.1",
92        note = "Use try_as_u32() or as_u32_saturating() instead to avoid panics"
93    )]
94    pub fn as_u32(&self) -> u32 {
95        self.0.to_u32().expect("NeoInteger value exceeds u32 range")
96    }
97
98    pub fn to_i32(&self) -> Option<i32> {
99        self.0.to_i32()
100    }
101
102    pub fn to_u32(&self) -> Option<u32> {
103        self.0.to_u32()
104    }
105}
106
107impl Not for NeoInteger {
108    type Output = Self;
109    fn not(self) -> Self::Output {
110        Self(!self.0)
111    }
112}
113
114impl Shl<u32> for NeoInteger {
115    type Output = Self;
116    fn shl(self, rhs: u32) -> Self::Output {
117        Self(self.0 << rhs)
118    }
119}
120
121impl Shl<u32> for &NeoInteger {
122    type Output = NeoInteger;
123    fn shl(self, rhs: u32) -> Self::Output {
124        NeoInteger::new(self.0.clone() << rhs)
125    }
126}
127
128impl Shr<u32> for NeoInteger {
129    type Output = Self;
130    fn shr(self, rhs: u32) -> Self::Output {
131        Self(self.0 >> rhs)
132    }
133}
134
135impl Shr<u32> for &NeoInteger {
136    type Output = NeoInteger;
137    fn shr(self, rhs: u32) -> Self::Output {
138        NeoInteger::new(self.0.clone() >> rhs)
139    }
140}
141
142impl From<i32> for NeoInteger {
143    fn from(value: i32) -> Self {
144        NeoInteger::new(value)
145    }
146}
147
148impl From<i64> for NeoInteger {
149    fn from(value: i64) -> Self {
150        NeoInteger::new(value)
151    }
152}
153
154impl From<u32> for NeoInteger {
155    fn from(value: u32) -> Self {
156        NeoInteger::new(value)
157    }
158}
159
160impl From<BigInt> for NeoInteger {
161    fn from(value: BigInt) -> Self {
162        NeoInteger::new(value)
163    }
164}
165
166impl From<&BigInt> for NeoInteger {
167    fn from(value: &BigInt) -> Self {
168        NeoInteger::new(value.clone())
169    }
170}
171
172impl Add for NeoInteger {
173    type Output = Self;
174    fn add(self, rhs: Self) -> Self::Output {
175        Self(self.0 + rhs.0)
176    }
177}
178
179impl Add<&NeoInteger> for NeoInteger {
180    type Output = Self;
181    fn add(self, rhs: &NeoInteger) -> Self::Output {
182        Self(self.0 + &rhs.0)
183    }
184}
185
186impl Add<NeoInteger> for &NeoInteger {
187    type Output = NeoInteger;
188    fn add(self, rhs: NeoInteger) -> Self::Output {
189        NeoInteger::new(&self.0 + rhs.0)
190    }
191}
192
193impl Add<&NeoInteger> for &NeoInteger {
194    type Output = NeoInteger;
195    fn add(self, rhs: &NeoInteger) -> Self::Output {
196        NeoInteger::new(&self.0 + &rhs.0)
197    }
198}
199
200impl Sub for NeoInteger {
201    type Output = Self;
202    fn sub(self, rhs: Self) -> Self::Output {
203        Self(self.0 - rhs.0)
204    }
205}
206
207impl Sub<&NeoInteger> for NeoInteger {
208    type Output = Self;
209    fn sub(self, rhs: &NeoInteger) -> Self::Output {
210        Self(self.0 - &rhs.0)
211    }
212}
213
214impl Sub<NeoInteger> for &NeoInteger {
215    type Output = NeoInteger;
216    fn sub(self, rhs: NeoInteger) -> Self::Output {
217        NeoInteger::new(&self.0 - rhs.0)
218    }
219}
220
221impl Sub<&NeoInteger> for &NeoInteger {
222    type Output = NeoInteger;
223    fn sub(self, rhs: &NeoInteger) -> Self::Output {
224        NeoInteger::new(&self.0 - &rhs.0)
225    }
226}
227
228impl Mul for NeoInteger {
229    type Output = Self;
230    fn mul(self, rhs: Self) -> Self::Output {
231        Self(self.0 * rhs.0)
232    }
233}
234
235impl Mul<&NeoInteger> for NeoInteger {
236    type Output = Self;
237    fn mul(self, rhs: &NeoInteger) -> Self::Output {
238        Self(self.0 * &rhs.0)
239    }
240}
241
242impl Mul<NeoInteger> for &NeoInteger {
243    type Output = NeoInteger;
244    fn mul(self, rhs: NeoInteger) -> Self::Output {
245        NeoInteger::new(&self.0 * rhs.0)
246    }
247}
248
249impl Mul<&NeoInteger> for &NeoInteger {
250    type Output = NeoInteger;
251    fn mul(self, rhs: &NeoInteger) -> Self::Output {
252        NeoInteger::new(&self.0 * &rhs.0)
253    }
254}
255
256impl Div for NeoInteger {
257    type Output = Self;
258    fn div(self, rhs: Self) -> Self::Output {
259        Self(self.0 / rhs.0)
260    }
261}
262
263impl Div<&NeoInteger> for NeoInteger {
264    type Output = Self;
265    fn div(self, rhs: &NeoInteger) -> Self::Output {
266        Self(self.0 / &rhs.0)
267    }
268}
269
270impl Div<NeoInteger> for &NeoInteger {
271    type Output = NeoInteger;
272    fn div(self, rhs: NeoInteger) -> Self::Output {
273        NeoInteger::new(&self.0 / rhs.0)
274    }
275}
276
277impl Div<&NeoInteger> for &NeoInteger {
278    type Output = NeoInteger;
279    fn div(self, rhs: &NeoInteger) -> Self::Output {
280        NeoInteger::new(&self.0 / &rhs.0)
281    }
282}
283
284impl Rem for NeoInteger {
285    type Output = Self;
286    fn rem(self, rhs: Self) -> Self::Output {
287        Self(self.0 % rhs.0)
288    }
289}
290
291impl Rem<&NeoInteger> for NeoInteger {
292    type Output = Self;
293    fn rem(self, rhs: &NeoInteger) -> Self::Output {
294        Self(self.0 % &rhs.0)
295    }
296}
297
298impl Rem<NeoInteger> for &NeoInteger {
299    type Output = NeoInteger;
300    fn rem(self, rhs: NeoInteger) -> Self::Output {
301        NeoInteger::new(&self.0 % rhs.0)
302    }
303}
304
305impl Rem<&NeoInteger> for &NeoInteger {
306    type Output = NeoInteger;
307    fn rem(self, rhs: &NeoInteger) -> Self::Output {
308        NeoInteger::new(&self.0 % &rhs.0)
309    }
310}
311
312impl BitAnd for NeoInteger {
313    type Output = Self;
314    fn bitand(self, rhs: Self) -> Self::Output {
315        Self(self.0 & rhs.0)
316    }
317}
318
319impl BitAnd<&NeoInteger> for NeoInteger {
320    type Output = Self;
321    fn bitand(self, rhs: &NeoInteger) -> Self::Output {
322        Self(self.0 & &rhs.0)
323    }
324}
325
326impl BitAnd<NeoInteger> for &NeoInteger {
327    type Output = NeoInteger;
328    fn bitand(self, rhs: NeoInteger) -> Self::Output {
329        NeoInteger::new(&self.0 & rhs.0)
330    }
331}
332
333impl BitAnd<&NeoInteger> for &NeoInteger {
334    type Output = NeoInteger;
335    fn bitand(self, rhs: &NeoInteger) -> Self::Output {
336        NeoInteger::new(&self.0 & &rhs.0)
337    }
338}
339
340impl BitOr for NeoInteger {
341    type Output = Self;
342    fn bitor(self, rhs: Self) -> Self::Output {
343        Self(self.0 | rhs.0)
344    }
345}
346
347impl BitOr<&NeoInteger> for NeoInteger {
348    type Output = Self;
349    fn bitor(self, rhs: &NeoInteger) -> Self::Output {
350        Self(self.0 | &rhs.0)
351    }
352}
353
354impl BitOr<NeoInteger> for &NeoInteger {
355    type Output = NeoInteger;
356    fn bitor(self, rhs: NeoInteger) -> Self::Output {
357        NeoInteger::new(&self.0 | rhs.0)
358    }
359}
360
361impl BitOr<&NeoInteger> for &NeoInteger {
362    type Output = NeoInteger;
363    fn bitor(self, rhs: &NeoInteger) -> Self::Output {
364        NeoInteger::new(&self.0 | &rhs.0)
365    }
366}
367
368impl BitXor for NeoInteger {
369    type Output = Self;
370    fn bitxor(self, rhs: Self) -> Self::Output {
371        Self(self.0 ^ rhs.0)
372    }
373}
374
375impl BitXor<&NeoInteger> for NeoInteger {
376    type Output = Self;
377    fn bitxor(self, rhs: &NeoInteger) -> Self::Output {
378        Self(self.0 ^ &rhs.0)
379    }
380}
381
382impl BitXor<NeoInteger> for &NeoInteger {
383    type Output = NeoInteger;
384    fn bitxor(self, rhs: NeoInteger) -> Self::Output {
385        NeoInteger::new(&self.0 ^ rhs.0)
386    }
387}
388
389impl BitXor<&NeoInteger> for &NeoInteger {
390    type Output = NeoInteger;
391    fn bitxor(self, rhs: &NeoInteger) -> Self::Output {
392        NeoInteger::new(&self.0 ^ &rhs.0)
393    }
394}
395
396impl Default for NeoInteger {
397    fn default() -> Self {
398        NeoInteger::zero()
399    }
400}