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