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