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;
16pub use parse::parse_uint;
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<'_>) -> std::fmt::Result {
161 write!(f, "{}", self.0)
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168
169 #[test]
170 fn test_uint_create() {
171 let uint = Uint::from_u64(42);
172 assert_eq!(format!("{}", uint), "42");
173 }
174
175 #[test]
176 fn test_uint_equality() {
177 let a = Uint::from_u64(100);
178 let b = Uint::from_u64(100);
179 let c = Uint::from_u64(200);
180
181 assert_eq!(a, b);
182 assert_ne!(a, c);
183 }
184
185 #[test]
186 fn test_uint_ordering() {
187 let a = Uint::from_u64(10);
188 let b = Uint::from_u64(20);
189 let c = Uint::from_u64(20);
190
191 assert!(a < b);
192 assert!(b > a);
193 assert_eq!(b.cmp(&c), Ordering::Equal);
194 }
195
196 #[test]
197 fn test_uint_large_values() {
198 let large = Uint::from_u128(u128::MAX);
199 let larger = Uint::from(StdBigInt::from(u128::MAX) + 1);
200
201 assert!(large < larger);
202 }
203
204 #[test]
205 fn test_uint_display() {
206 let uint = Uint::from_u64(12345);
207 assert_eq!(format!("{}", uint), "12345");
208 }
209
210 #[test]
211 fn test_uint_hash() {
212 use std::collections::HashSet;
213
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}