Skip to main content

reifydb_type/value/int/
mod.rs

1// SPDX-License-Identifier: MIT
2// Copyright (c) 2025 ReifyDB
3
4use std::{
5	cmp::Ordering,
6	fmt::{Display, Formatter},
7	hash::{Hash, Hasher},
8	ops::Deref,
9};
10
11use num_bigint::BigInt as StdBigInt;
12use serde::{Deserialize, Serialize};
13
14pub mod parse;
15
16/// A wrapper type for arbitrary-precision signed integers (Int)
17#[repr(transparent)]
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19pub struct Int(pub StdBigInt);
20
21impl Int {
22	/// Create a new Int from an i64
23	pub fn from_i64(value: i64) -> Self {
24		Int(StdBigInt::from(value))
25	}
26
27	/// Create a new Int from an i128
28	pub fn from_i128(value: i128) -> Self {
29		Int(StdBigInt::from(value))
30	}
31
32	/// Create a Int representing zero
33	pub fn zero() -> Self {
34		Int(StdBigInt::from(0))
35	}
36
37	/// Create a Int representing one
38	pub fn one() -> Self {
39		Int(StdBigInt::from(1))
40	}
41}
42
43impl Default for Int {
44	fn default() -> Self {
45		Self::zero()
46	}
47}
48
49impl Deref for Int {
50	type Target = StdBigInt;
51
52	fn deref(&self) -> &Self::Target {
53		&self.0
54	}
55}
56
57impl Hash for Int {
58	fn hash<H: Hasher>(&self, state: &mut H) {
59		self.0.hash(state);
60	}
61}
62
63impl PartialOrd for Int {
64	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
65		Some(self.cmp(other))
66	}
67}
68
69impl Ord for Int {
70	fn cmp(&self, other: &Self) -> Ordering {
71		self.0.cmp(&other.0)
72	}
73}
74
75impl From<i8> for Int {
76	fn from(value: i8) -> Self {
77		Int(StdBigInt::from(value))
78	}
79}
80
81impl From<i16> for Int {
82	fn from(value: i16) -> Self {
83		Int(StdBigInt::from(value))
84	}
85}
86
87impl From<i32> for Int {
88	fn from(value: i32) -> Self {
89		Int(StdBigInt::from(value))
90	}
91}
92
93impl From<i64> for Int {
94	fn from(value: i64) -> Self {
95		Int(StdBigInt::from(value))
96	}
97}
98
99impl From<i128> for Int {
100	fn from(value: i128) -> Self {
101		Int(StdBigInt::from(value))
102	}
103}
104
105impl From<u8> for Int {
106	fn from(value: u8) -> Self {
107		Int(StdBigInt::from(value))
108	}
109}
110
111impl From<u16> for Int {
112	fn from(value: u16) -> Self {
113		Int(StdBigInt::from(value))
114	}
115}
116
117impl From<u32> for Int {
118	fn from(value: u32) -> Self {
119		Int(StdBigInt::from(value))
120	}
121}
122
123impl From<u64> for Int {
124	fn from(value: u64) -> Self {
125		Int(StdBigInt::from(value))
126	}
127}
128
129impl From<u128> for Int {
130	fn from(value: u128) -> Self {
131		Int(StdBigInt::from(value))
132	}
133}
134
135impl From<StdBigInt> for Int {
136	fn from(value: StdBigInt) -> Self {
137		Int(value)
138	}
139}
140
141impl From<Int> for StdBigInt {
142	fn from(int: Int) -> Self {
143		int.0
144	}
145}
146
147impl Display for Int {
148	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
149		write!(f, "{}", self.0)
150	}
151}
152
153#[cfg(test)]
154pub mod tests {
155	use super::*;
156
157	#[test]
158	fn test_int_create() {
159		let int = Int::from_i64(42);
160		assert_eq!(format!("{}", int), "42");
161	}
162
163	#[test]
164	fn test_int_equality() {
165		let a = Int::from_i64(100);
166		let b = Int::from_i64(100);
167		let c = Int::from_i64(200);
168
169		assert_eq!(a, b);
170		assert_ne!(a, c);
171	}
172
173	#[test]
174	fn test_int_ordering() {
175		let a = Int::from_i64(10);
176		let b = Int::from_i64(20);
177		let c = Int::from_i64(20);
178
179		assert!(a < b);
180		assert!(b > a);
181		assert_eq!(b.cmp(&c), Ordering::Equal);
182	}
183
184	#[test]
185	fn test_int_large_values() {
186		let large = Int::from_i128(i128::MAX);
187		let larger = Int::from(StdBigInt::from(i128::MAX) + 1);
188
189		assert!(large < larger);
190	}
191
192	#[test]
193	fn test_int_display() {
194		let int = Int::from_i64(-12345);
195		assert_eq!(format!("{}", int), "-12345");
196	}
197
198	#[test]
199	fn test_int_hash() {
200		use std::collections::HashSet;
201
202		let a = Int::from_i64(42);
203		let b = Int::from_i64(42);
204
205		let mut set = HashSet::new();
206		set.insert(a);
207		assert!(set.contains(&b));
208	}
209}