quickjs_rusty/value/
bigint.rs1use num_traits::cast::ToPrimitive;
2
3#[derive(Clone, Debug)]
4pub enum BigIntOrI64 {
5 Int(i64),
6 BigInt(num_bigint::BigInt),
7}
8
9impl PartialEq for BigIntOrI64 {
10 fn eq(&self, other: &Self) -> bool {
11 use BigIntOrI64::*;
12 match (&self, &other) {
13 (Int(i), Int(j)) => i == j,
14 (Int(i), BigInt(b)) | (BigInt(b), Int(i)) => b == &num_bigint::BigInt::from(*i),
15 (BigInt(a), BigInt(b)) => a == b,
16 }
17 }
18}
19
20impl Eq for BigIntOrI64 {}
21
22#[derive(Clone, Debug, PartialEq, Eq)]
25pub struct BigInt {
26 pub(crate) inner: BigIntOrI64,
27}
28
29impl BigInt {
30 pub fn as_i64(&self) -> Option<i64> {
32 match &self.inner {
33 BigIntOrI64::Int(int) => Some(*int),
34 BigIntOrI64::BigInt(bigint) => bigint.to_i64(),
35 }
36 }
37 pub fn into_bigint(self) -> num_bigint::BigInt {
39 match self.inner {
40 BigIntOrI64::Int(int) => int.into(),
41 BigIntOrI64::BigInt(bigint) => bigint,
42 }
43 }
44}
45
46impl std::fmt::Display for BigInt {
47 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
48 match self.inner {
49 BigIntOrI64::Int(i) => write!(f, "{}", i),
50 BigIntOrI64::BigInt(ref i) => write!(f, "{}", i),
51 }
52 }
53}
54
55impl From<i64> for BigInt {
56 fn from(int: i64) -> Self {
57 BigInt {
58 inner: BigIntOrI64::Int(int),
59 }
60 }
61}
62
63impl From<num_bigint::BigInt> for BigInt {
64 fn from(bigint: num_bigint::BigInt) -> Self {
65 BigInt {
66 inner: BigIntOrI64::BigInt(bigint),
67 }
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 #[allow(unused_imports)]
74 use super::*;
75
76 #[test]
77 fn test_bigint_as_i64() {
78 let value = BigInt {
79 inner: BigIntOrI64::Int(1234i64),
80 };
81 assert_eq!(value.as_i64(), Some(1234i64));
82 }
83
84 #[test]
85 fn test_bigint_as_i64_overflow() {
86 let value = BigInt {
87 inner: BigIntOrI64::BigInt(num_bigint::BigInt::from(std::i128::MAX)),
88 };
89 assert_eq!(value.as_i64(), None);
90 }
91
92 #[test]
93 fn test_bigint_into_bigint() {
94 for i in [
95 0_i128,
96 std::i64::MAX as i128,
97 std::i64::MIN as i128,
98 std::i128::MAX,
99 std::i128::MIN,
100 ] {
101 let value = BigInt {
102 inner: BigIntOrI64::BigInt(num_bigint::BigInt::from(i)),
103 };
104 assert_eq!(value.into_bigint(), num_bigint::BigInt::from(i));
105 }
106 }
107}