reifydb_value/value/number/safe/convert/
uint.rs1use bigdecimal::BigDecimal as BigDecimalInner;
5
6use super::*;
7
8macro_rules! impl_safe_convert_uint_to_signed {
9 ($($dst:ty),*) => {
10 $(
11 impl SafeConvert<$dst> for Uint {
12 fn checked_convert(self) -> Option<$dst> {
13 <$dst>::try_from(&self.0).ok()
14 }
15
16 fn saturating_convert(self) -> $dst {
17 if let Ok(val) = <$dst>::try_from(&self.0) {
18 val
19 } else {
20 <$dst>::MAX
21 }
22 }
23
24 fn wrapping_convert(self) -> $dst {
25 if let Ok(val) = u64::try_from(&self.0) {
26 val as $dst
27 } else {
28 self.saturating_convert()
29 }
30 }
31 }
32 )*
33 };
34}
35
36macro_rules! impl_safe_convert_uint_to_unsigned {
37 ($($dst:ty),*) => {
38 $(
39 impl SafeConvert<$dst> for Uint {
40 fn checked_convert(self) -> Option<$dst> {
41 <$dst>::try_from(&self.0).ok()
42 }
43
44 fn saturating_convert(self) -> $dst {
45 if let Ok(val) = <$dst>::try_from(&self.0) {
46 val
47 } else {
48 <$dst>::MAX
49 }
50 }
51
52 fn wrapping_convert(self) -> $dst {
53 if let Ok(val) = u64::try_from(&self.0) {
54 val as $dst
55 } else {
56 self.saturating_convert()
57 }
58 }
59 }
60 )*
61 };
62}
63
64macro_rules! impl_safe_convert_uint_to_float {
65 ($($dst:ty),*) => {
66 $(
67 impl SafeConvert<$dst> for Uint {
68 fn checked_convert(self) -> Option<$dst> {
69 self.0.to_f64().and_then(|f| {
70 if f.is_finite() {
71 Some(f as $dst)
72 } else {
73 None
74 }
75 })
76 }
77
78 fn saturating_convert(self) -> $dst {
79 if let Some(f) = self.0.to_f64() {
80 if f.is_finite() {
81 f as $dst
82 } else {
83 <$dst>::MAX
84 }
85 } else {
86 <$dst>::MAX
87 }
88 }
89
90 fn wrapping_convert(self) -> $dst {
91 self.saturating_convert()
92 }
93 }
94 )*
95 };
96}
97
98impl_safe_convert_uint_to_signed!(i8, i16, i32, i64, i128);
99impl_safe_convert_uint_to_unsigned!(u8, u16, u32, u64, u128);
100impl_safe_convert_uint_to_float!(f32, f64);
101
102impl SafeConvert<Int> for Uint {
103 fn checked_convert(self) -> Option<Int> {
104 Some(Int(self.0))
105 }
106
107 fn saturating_convert(self) -> Int {
108 Int(self.0)
109 }
110
111 fn wrapping_convert(self) -> Int {
112 Int(self.0)
113 }
114}
115
116impl SafeConvert<Decimal> for Uint {
117 fn checked_convert(self) -> Option<Decimal> {
118 let big_decimal = BigDecimalInner::from(self.0);
119 Some(Decimal::from(big_decimal))
120 }
121
122 fn saturating_convert(self) -> Decimal {
123 let big_decimal = BigDecimalInner::from(self.0);
124 Decimal::from(big_decimal)
125 }
126
127 fn wrapping_convert(self) -> Decimal {
128 self.saturating_convert()
129 }
130}
131
132#[cfg(test)]
133pub mod tests {
134 use super::*;
135 mod i8 {
136 use super::*;
137
138 #[test]
139 fn test_checked_convert() {
140 let x = Uint::from(127u8);
141 let y: Option<i8> = x.checked_convert();
142 assert_eq!(y, Some(127i8));
143 }
144
145 #[test]
146 fn test_checked_convert_overflow() {
147 let x = Uint::from(128u8);
148 let y: Option<i8> = x.checked_convert();
149 assert_eq!(y, None);
150 }
151
152 #[test]
153 fn test_saturating_convert() {
154 let x = Uint::from(200u8);
155 let y: i8 = x.saturating_convert();
156 assert_eq!(y, i8::MAX);
157 }
158 }
159
160 mod i32 {
161 use super::*;
162
163 #[test]
164 fn test_checked_convert() {
165 let x = Uint::from(2147483647u32);
166 let y: Option<i32> = x.checked_convert();
167 assert_eq!(y, Some(2147483647i32));
168 }
169
170 #[test]
171 fn test_saturating_convert() {
172 let x = Uint::from(2147483648u32);
173 let y: i32 = x.saturating_convert();
174 assert_eq!(y, i32::MAX);
175 }
176 }
177
178 mod u8 {
179 use super::*;
180
181 #[test]
182 fn test_checked_convert() {
183 let x = Uint::from(255u16);
184 let y: Option<u8> = x.checked_convert();
185 assert_eq!(y, Some(255u8));
186 }
187
188 #[test]
189 fn test_checked_convert_overflow() {
190 let x = Uint::from(256u16);
191 let y: Option<u8> = x.checked_convert();
192 assert_eq!(y, None);
193 }
194
195 #[test]
196 fn test_saturating_convert() {
197 let x = Uint::from(1000u16);
198 let y: u8 = x.saturating_convert();
199 assert_eq!(y, u8::MAX);
200 }
201 }
202
203 mod u32 {
204 use super::*;
205
206 #[test]
207 fn test_checked_convert() {
208 let x = Uint::from(4294967295u64);
209 let y: Option<u32> = x.checked_convert();
210 assert_eq!(y, Some(4294967295u32));
211 }
212
213 #[test]
214 fn test_saturating_convert() {
215 let x = Uint::from(4294967296u64);
216 let y: u32 = x.saturating_convert();
217 assert_eq!(y, u32::MAX);
218 }
219 }
220
221 mod f32 {
222 use super::*;
223
224 #[test]
225 fn test_checked_convert() {
226 let x = Uint::from(42u32);
227 let y: Option<f32> = x.checked_convert();
228 assert_eq!(y, Some(42.0f32));
229 }
230
231 #[test]
232 fn test_saturating_convert() {
233 let x = Uint::from(1000u32);
234 let y: f32 = x.saturating_convert();
235 assert_eq!(y, 1000.0f32);
236 }
237 }
238
239 mod f64 {
240 use super::*;
241
242 #[test]
243 fn test_checked_convert() {
244 let x = Uint::from(42u32);
245 let y: Option<f64> = x.checked_convert();
246 assert_eq!(y, Some(42.0f64));
247 }
248
249 #[test]
250 fn test_saturating_convert() {
251 let x = Uint::from(1000u32);
252 let y: f64 = x.saturating_convert();
253 assert_eq!(y, 1000.0f64);
254 }
255 }
256
257 mod int {
258 use super::*;
259
260 #[test]
261 fn test_checked_convert() {
262 let x = Uint::from(42u32);
263 let y: Option<Int> = x.checked_convert();
264 assert!(y.is_some());
265 assert_eq!(y.unwrap().to_string(), "42");
266 }
267
268 #[test]
269 fn test_saturating_convert() {
270 let x = Uint::from(100u32);
271 let y: Int = x.saturating_convert();
272 assert_eq!(y.to_string(), "100");
273 }
274
275 #[test]
276 fn test_wrapping_convert() {
277 let x = Uint::from(0u32);
278 let y: Int = x.wrapping_convert();
279 assert_eq!(y.to_string(), "0");
280 }
281 }
282
283 mod decimal {
284 use super::*;
285
286 #[test]
287 fn test_checked_convert() {
288 let x = Uint::from(12345u32);
289 let y: Option<Decimal> = x.checked_convert();
290 assert!(y.is_some());
291 let decimal = y.unwrap();
292 assert_eq!(decimal.to_string(), "12345");
293 }
294
295 #[test]
296 fn test_checked_convert_zero() {
297 let x = Uint::from(0u32);
298 let y: Option<Decimal> = x.checked_convert();
299 assert!(y.is_some());
300 let decimal = y.unwrap();
301 assert_eq!(decimal.to_string(), "0");
302 }
303
304 #[test]
305 fn test_checked_convert_large() {
306 let x = Uint::from(u128::MAX);
308 let y: Option<Decimal> = x.checked_convert();
309 assert!(y.is_some());
310 let decimal = y.unwrap();
311 assert_eq!(decimal.to_string(), "340282366920938463463374607431768211455");
312 }
313
314 #[test]
315 fn test_saturating_convert() {
316 let x = Uint::from(999999u32);
317 let y: Decimal = x.saturating_convert();
318 assert_eq!(y.to_string(), "999999");
319 }
320
321 #[test]
322 fn test_wrapping_convert() {
323 let x = Uint::from(100u32);
324 let y: Decimal = x.wrapping_convert();
325 assert_eq!(y.to_string(), "100");
326 }
327 }
328
329 mod self_conversion {
330 use super::*;
331
332 #[test]
333 fn test_checked_convert() {
334 let x = Uint::from(42u32);
335 let y: Option<Uint> = x.clone().checked_convert();
336 assert_eq!(y, Some(x));
337 }
338
339 #[test]
340 fn test_saturating_convert() {
341 let x = Uint::from(100u32);
342 let y: Uint = x.clone().saturating_convert();
343 assert_eq!(y, x);
344 }
345
346 #[test]
347 fn test_wrapping_convert() {
348 let x = Uint::from(999u32);
349 let y: Uint = x.clone().wrapping_convert();
350 assert_eq!(y, x);
351 }
352 }
353}