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