reifydb_value/value/number/safe/convert/
f64.rs1use super::*;
5
6impl_safe_convert_float_demote!(f64 => f32);
7
8impl_safe_convert_float_to_signed!(f64 => i8, i16, i32, i64, i128);
9
10impl_safe_convert_float_to_unsigned!(f64 => u8, u16, u32, u64, u128);
11
12impl_safe_convert_float_to_int!(f64);
13impl_safe_convert_float_to_uint!(f64);
14
15impl_safe_convert_to_decimal_from_float!(f64);
16
17#[cfg(test)]
18pub mod tests {
19
20 mod f32 {
21 use super::*;
22 use crate::value::number::safe::convert::SafeConvert;
23
24 #[test]
25 fn test_checked_convert_happy() {
26 let x: f64 = 123.0;
27 let y: Option<f32> = x.checked_convert();
28 assert_eq!(y, Some(123.0f32));
29 }
30
31 #[test]
32 fn test_checked_convert_unhappy_due_to_infinity() {
33 let x: f64 = f64::MAX;
34 let y: Option<f32> = x.checked_convert();
35 assert_eq!(y, None);
36 }
37
38 #[test]
39 fn test_checked_convert_unhappy_due_to_negative_infinity() {
40 let x: f64 = f64::MIN;
41 let y: Option<f32> = x.checked_convert();
42 assert_eq!(y, None);
43 }
44
45 #[test]
46 fn test_saturating_convert_within_range() {
47 let x: f64 = 456.789;
48 let y: f32 = x.saturating_convert();
49 assert_eq!(y, 456.789f32);
50 }
51
52 #[test]
53 fn test_saturating_convert_too_large() {
54 let x: f64 = f64::MAX;
55 let y: f32 = x.saturating_convert();
56 assert_eq!(y, f32::MAX);
57 }
58
59 #[test]
60 fn test_saturating_convert_too_small() {
61 let x: f64 = f64::MIN;
62 let y: f32 = x.saturating_convert();
63 assert_eq!(y, f32::MIN);
64 }
65
66 #[test]
67 fn test_saturating_convert_nan() {
68 let x: f64 = f64::NAN;
69 let y: f32 = x.saturating_convert();
70 assert!(y.is_nan());
71 }
72
73 #[test]
74 fn test_wrapping_convert_regular() {
75 let x: f64 = 789.123;
76 let y: f32 = x.wrapping_convert();
77 assert_eq!(y, 789.123f32);
78 }
79
80 #[test]
81 fn test_wrapping_convert_nan() {
82 let x: f64 = f64::NAN;
83 let y: f32 = x.wrapping_convert();
84 assert!(y.is_nan());
85 }
86
87 #[test]
88 fn test_wrapping_convert_infinity() {
89 let x: f64 = f64::INFINITY;
90 let y: f32 = x.wrapping_convert();
91 assert!(y.is_infinite() && y.is_sign_positive());
92 }
93 }
94
95 mod i8 {
96 use crate::value::number::safe::convert::SafeConvert;
97
98 #[test]
99 fn test_checked_convert_happy() {
100 let x: f64 = 42.0;
101 let y: Option<i8> = x.checked_convert();
102 assert_eq!(y, Some(42i8));
103 }
104
105 #[test]
106 fn test_checked_convert_unhappy() {
107 let x: f64 = 300.0;
108 let y: Option<i8> = x.checked_convert();
109 assert_eq!(y, None);
110 }
111
112 #[test]
113 fn test_checked_convert_negative() {
114 let x: f64 = -42.0;
115 let y: Option<i8> = x.checked_convert();
116 assert_eq!(y, Some(-42i8));
117 }
118
119 #[test]
120 fn test_checked_convert_nan() {
121 let x: f64 = f64::NAN;
122 let y: Option<i8> = x.checked_convert();
123 assert_eq!(y, None);
124 }
125
126 #[test]
127 fn test_checked_convert_infinity() {
128 let x: f64 = f64::INFINITY;
129 let y: Option<i8> = x.checked_convert();
130 assert_eq!(y, None);
131 }
132
133 #[test]
134 fn test_saturating_convert_overflow() {
135 let x: f64 = 300.0;
136 let y: i8 = x.saturating_convert();
137 assert_eq!(y, i8::MAX);
138 }
139
140 #[test]
141 fn test_saturating_convert_underflow() {
142 let x: f64 = -300.0;
143 let y: i8 = x.saturating_convert();
144 assert_eq!(y, i8::MIN);
145 }
146
147 #[test]
148 fn test_saturating_convert_nan() {
149 let x: f64 = f64::NAN;
150 let y: i8 = x.saturating_convert();
151 assert_eq!(y, 0);
152 }
153
154 #[test]
155 fn test_saturating_convert_infinity() {
156 let x: f64 = f64::INFINITY;
157 let y: i8 = x.saturating_convert();
158 assert_eq!(y, i8::MAX);
159 }
160
161 #[test]
162 fn test_saturating_convert_neg_infinity() {
163 let x: f64 = f64::NEG_INFINITY;
164 let y: i8 = x.saturating_convert();
165 assert_eq!(y, i8::MIN);
166 }
167
168 #[test]
169 fn test_wrapping_convert() {
170 let x: f64 = 42.0;
171 let y: i8 = x.wrapping_convert();
172 assert_eq!(y, 42i8);
173 }
174
175 #[test]
176 fn test_wrapping_convert_nan() {
177 let x: f64 = f64::NAN;
178 let y: i8 = x.wrapping_convert();
179 assert_eq!(y, 0);
180 }
181 }
182
183 mod i16 {
184 use crate::value::number::safe::convert::SafeConvert;
185
186 #[test]
187 fn test_checked_convert_happy() {
188 let x: f64 = 42.0;
189 let y: Option<i16> = x.checked_convert();
190 assert_eq!(y, Some(42i16));
191 }
192
193 #[test]
194 fn test_checked_convert_unhappy() {
195 let x: f64 = 40000.0;
196 let y: Option<i16> = x.checked_convert();
197 assert_eq!(y, None);
198 }
199
200 #[test]
201 fn test_checked_convert_negative() {
202 let x: f64 = -42.0;
203 let y: Option<i16> = x.checked_convert();
204 assert_eq!(y, Some(-42i16));
205 }
206
207 #[test]
208 fn test_checked_convert_nan() {
209 let x: f64 = f64::NAN;
210 let y: Option<i16> = x.checked_convert();
211 assert_eq!(y, None);
212 }
213
214 #[test]
215 fn test_saturating_convert_overflow() {
216 let x: f64 = 40000.0;
217 let y: i16 = x.saturating_convert();
218 assert_eq!(y, i16::MAX);
219 }
220
221 #[test]
222 fn test_saturating_convert_underflow() {
223 let x: f64 = -40000.0;
224 let y: i16 = x.saturating_convert();
225 assert_eq!(y, i16::MIN);
226 }
227
228 #[test]
229 fn test_wrapping_convert() {
230 let x: f64 = 42.0;
231 let y: i16 = x.wrapping_convert();
232 assert_eq!(y, 42i16);
233 }
234 }
235
236 mod i32 {
237 use crate::value::number::safe::convert::SafeConvert;
238
239 #[test]
240 fn test_checked_convert_happy() {
241 let x: f64 = 42.0;
242 let y: Option<i32> = x.checked_convert();
243 assert_eq!(y, Some(42i32));
244 }
245
246 #[test]
247 fn test_checked_convert_unhappy() {
248 let x: f64 = 3e38;
249 let y: Option<i32> = x.checked_convert();
250 assert_eq!(y, None);
251 }
252
253 #[test]
254 fn test_checked_convert_negative() {
255 let x: f64 = -42.0;
256 let y: Option<i32> = x.checked_convert();
257 assert_eq!(y, Some(-42i32));
258 }
259
260 #[test]
261 fn test_saturating_convert_overflow() {
262 let x: f64 = 3e38;
263 let y: i32 = x.saturating_convert();
264 assert_eq!(y, i32::MAX);
265 }
266
267 #[test]
268 fn test_saturating_convert_underflow() {
269 let x: f64 = -3e38;
270 let y: i32 = x.saturating_convert();
271 assert_eq!(y, i32::MIN);
272 }
273
274 #[test]
275 fn test_wrapping_convert() {
276 let x: f64 = 42.0;
277 let y: i32 = x.wrapping_convert();
278 assert_eq!(y, 42i32);
279 }
280 }
281
282 mod i64 {
283 use crate::value::number::safe::convert::SafeConvert;
284
285 #[test]
286 fn test_checked_convert_happy() {
287 let x: f64 = 42.0;
288 let y: Option<i64> = x.checked_convert();
289 assert_eq!(y, Some(42i64));
290 }
291
292 #[test]
293 fn test_checked_convert_unhappy() {
294 let x: f64 = 1e300;
295 let y: Option<i64> = x.checked_convert();
296 assert_eq!(y, None);
297 }
298
299 #[test]
300 fn test_checked_convert_negative() {
301 let x: f64 = -42.0;
302 let y: Option<i64> = x.checked_convert();
303 assert_eq!(y, Some(-42i64));
304 }
305
306 #[test]
307 fn test_saturating_convert_overflow() {
308 let x: f64 = 1e300;
309 let y: i64 = x.saturating_convert();
310 assert_eq!(y, i64::MAX);
311 }
312
313 #[test]
314 fn test_saturating_convert_underflow() {
315 let x: f64 = -1e300;
316 let y: i64 = x.saturating_convert();
317 assert_eq!(y, i64::MIN);
318 }
319
320 #[test]
321 fn test_wrapping_convert() {
322 let x: f64 = 42.0;
323 let y: i64 = x.wrapping_convert();
324 assert_eq!(y, 42i64);
325 }
326 }
327
328 mod i128 {
329 use crate::value::number::safe::convert::SafeConvert;
330
331 #[test]
332 fn test_checked_convert_happy() {
333 let x: f64 = 42.0;
334 let y: Option<i128> = x.checked_convert();
335 assert_eq!(y, Some(42i128));
336 }
337
338 #[test]
339 fn test_checked_convert_unhappy() {
340 let x: f64 = 1e300;
341 let y: Option<i128> = x.checked_convert();
342 assert_eq!(y, None);
343 }
344
345 #[test]
346 fn test_checked_convert_negative() {
347 let x: f64 = -42.0;
348 let y: Option<i128> = x.checked_convert();
349 assert_eq!(y, Some(-42i128));
350 }
351
352 #[test]
353 fn test_saturating_convert_overflow() {
354 let x: f64 = 1e300;
355 let y: i128 = x.saturating_convert();
356 assert_eq!(y, i128::MAX);
357 }
358
359 #[test]
360 fn test_saturating_convert_underflow() {
361 let x: f64 = -1e300;
362 let y: i128 = x.saturating_convert();
363 assert_eq!(y, i128::MIN);
364 }
365
366 #[test]
367 fn test_wrapping_convert() {
368 let x: f64 = 42.0;
369 let y: i128 = x.wrapping_convert();
370 assert_eq!(y, 42i128);
371 }
372 }
373
374 mod u8 {
375 use crate::value::number::safe::convert::SafeConvert;
376
377 #[test]
378 fn test_checked_convert_happy() {
379 let x: f64 = 42.0;
380 let y: Option<u8> = x.checked_convert();
381 assert_eq!(y, Some(42u8));
382 }
383
384 #[test]
385 fn test_checked_convert_unhappy() {
386 let x: f64 = 300.0;
387 let y: Option<u8> = x.checked_convert();
388 assert_eq!(y, None);
389 }
390
391 #[test]
392 fn test_checked_convert_negative() {
393 let x: f64 = -42.0;
394 let y: Option<u8> = x.checked_convert();
395 assert_eq!(y, None);
396 }
397
398 #[test]
399 fn test_checked_convert_nan() {
400 let x: f64 = f64::NAN;
401 let y: Option<u8> = x.checked_convert();
402 assert_eq!(y, None);
403 }
404
405 #[test]
406 fn test_checked_convert_infinity() {
407 let x: f64 = f64::INFINITY;
408 let y: Option<u8> = x.checked_convert();
409 assert_eq!(y, None);
410 }
411
412 #[test]
413 fn test_saturating_convert_overflow() {
414 let x: f64 = 300.0;
415 let y: u8 = x.saturating_convert();
416 assert_eq!(y, u8::MAX);
417 }
418
419 #[test]
420 fn test_saturating_convert_underflow() {
421 let x: f64 = -42.0;
422 let y: u8 = x.saturating_convert();
423 assert_eq!(y, 0);
424 }
425
426 #[test]
427 fn test_saturating_convert_nan() {
428 let x: f64 = f64::NAN;
429 let y: u8 = x.saturating_convert();
430 assert_eq!(y, 0);
431 }
432
433 #[test]
434 fn test_saturating_convert_infinity() {
435 let x: f64 = f64::INFINITY;
436 let y: u8 = x.saturating_convert();
437 assert_eq!(y, u8::MAX);
438 }
439
440 #[test]
441 fn test_wrapping_convert() {
442 let x: f64 = 42.0;
443 let y: u8 = x.wrapping_convert();
444 assert_eq!(y, 42u8);
445 }
446
447 #[test]
448 fn test_wrapping_convert_negative() {
449 let x: f64 = -42.0;
450 let y: u8 = x.wrapping_convert();
451 assert_eq!(y, 0);
452 }
453 }
454
455 mod u16 {
456 use crate::value::number::safe::convert::SafeConvert;
457
458 #[test]
459 fn test_checked_convert_happy() {
460 let x: f64 = 42.0;
461 let y: Option<u16> = x.checked_convert();
462 assert_eq!(y, Some(42u16));
463 }
464
465 #[test]
466 fn test_checked_convert_unhappy() {
467 let x: f64 = 70000.0;
468 let y: Option<u16> = x.checked_convert();
469 assert_eq!(y, None);
470 }
471
472 #[test]
473 fn test_checked_convert_negative() {
474 let x: f64 = -42.0;
475 let y: Option<u16> = x.checked_convert();
476 assert_eq!(y, None);
477 }
478
479 #[test]
480 fn test_saturating_convert_overflow() {
481 let x: f64 = 70000.0;
482 let y: u16 = x.saturating_convert();
483 assert_eq!(y, u16::MAX);
484 }
485
486 #[test]
487 fn test_saturating_convert_underflow() {
488 let x: f64 = -42.0;
489 let y: u16 = x.saturating_convert();
490 assert_eq!(y, 0);
491 }
492
493 #[test]
494 fn test_wrapping_convert() {
495 let x: f64 = 42.0;
496 let y: u16 = x.wrapping_convert();
497 assert_eq!(y, 42u16);
498 }
499 }
500
501 mod u32 {
502 use crate::value::number::safe::convert::SafeConvert;
503
504 #[test]
505 fn test_checked_convert_happy() {
506 let x: f64 = 42.0;
507 let y: Option<u32> = x.checked_convert();
508 assert_eq!(y, Some(42u32));
509 }
510
511 #[test]
512 fn test_checked_convert_unhappy() {
513 let x: f64 = 1e300;
514 let y: Option<u32> = x.checked_convert();
515 assert_eq!(y, None);
516 }
517
518 #[test]
519 fn test_checked_convert_negative() {
520 let x: f64 = -42.0;
521 let y: Option<u32> = x.checked_convert();
522 assert_eq!(y, None);
523 }
524
525 #[test]
526 fn test_saturating_convert_overflow() {
527 let x: f64 = 1e300;
528 let y: u32 = x.saturating_convert();
529 assert_eq!(y, u32::MAX);
530 }
531
532 #[test]
533 fn test_saturating_convert_underflow() {
534 let x: f64 = -42.0;
535 let y: u32 = x.saturating_convert();
536 assert_eq!(y, 0);
537 }
538
539 #[test]
540 fn test_wrapping_convert() {
541 let x: f64 = 42.0;
542 let y: u32 = x.wrapping_convert();
543 assert_eq!(y, 42u32);
544 }
545 }
546
547 mod u64 {
548 use crate::value::number::safe::convert::SafeConvert;
549
550 #[test]
551 fn test_checked_convert_happy() {
552 let x: f64 = 42.0;
553 let y: Option<u64> = x.checked_convert();
554 assert_eq!(y, Some(42u64));
555 }
556
557 #[test]
558 fn test_checked_convert_unhappy() {
559 let x: f64 = 1e300;
560 let y: Option<u64> = x.checked_convert();
561 assert_eq!(y, None);
562 }
563
564 #[test]
565 fn test_checked_convert_negative() {
566 let x: f64 = -42.0;
567 let y: Option<u64> = x.checked_convert();
568 assert_eq!(y, None);
569 }
570
571 #[test]
572 fn test_saturating_convert_overflow() {
573 let x: f64 = 1e300;
574 let y: u64 = x.saturating_convert();
575 assert_eq!(y, u64::MAX);
576 }
577
578 #[test]
579 fn test_saturating_convert_underflow() {
580 let x: f64 = -42.0;
581 let y: u64 = x.saturating_convert();
582 assert_eq!(y, 0);
583 }
584
585 #[test]
586 fn test_wrapping_convert() {
587 let x: f64 = 42.0;
588 let y: u64 = x.wrapping_convert();
589 assert_eq!(y, 42u64);
590 }
591 }
592
593 mod u128 {
594 use crate::value::number::safe::convert::SafeConvert;
595
596 #[test]
597 fn test_checked_convert_happy() {
598 let x: f64 = 42.0;
599 let y: Option<u128> = x.checked_convert();
600 assert_eq!(y, Some(42u128));
601 }
602
603 #[test]
604 fn test_checked_convert_unhappy() {
605 let x: f64 = 1e300;
606 let y: Option<u128> = x.checked_convert();
607 assert_eq!(y, None);
608 }
609
610 #[test]
611 fn test_checked_convert_negative() {
612 let x: f64 = -42.0;
613 let y: Option<u128> = x.checked_convert();
614 assert_eq!(y, None);
615 }
616
617 #[test]
618 fn test_saturating_convert_overflow() {
619 let x: f64 = 1e300;
620 let y: u128 = x.saturating_convert();
621 assert_eq!(y, u128::MAX);
622 }
623
624 #[test]
625 fn test_saturating_convert_underflow() {
626 let x: f64 = -42.0;
627 let y: u128 = x.saturating_convert();
628 assert_eq!(y, 0);
629 }
630
631 #[test]
632 fn test_wrapping_convert() {
633 let x: f64 = 42.0;
634 let y: u128 = x.wrapping_convert();
635 assert_eq!(y, 42u128);
636 }
637 }
638
639 mod decimal {
640 use crate::value::{decimal::Decimal, number::safe::convert::SafeConvert};
641
642 #[test]
643 fn test_checked_convert() {
644 let x: f64 = 42.5;
645 let y: Option<Decimal> = x.checked_convert();
646 assert!(y.is_some());
647 let decimal = y.unwrap();
648 assert_eq!(decimal.to_string(), "42.5");
649 }
650
651 #[test]
652 fn test_checked_convert_high_precision() {
653 let x: f64 = 123.456789;
654 let y: Option<Decimal> = x.checked_convert();
655 assert!(y.is_some());
656 let decimal = y.unwrap();
657 assert!(decimal.to_string().starts_with("123.456789"));
659 }
662
663 #[test]
664 fn test_checked_convert_integer() {
665 let x: f64 = 1000.0;
666 let y: Option<Decimal> = x.checked_convert();
667 assert!(y.is_some());
668 let decimal = y.unwrap();
669 assert_eq!(decimal.to_string(), "1000");
670 }
671
672 #[test]
673 fn test_checked_convert_small_decimal() {
674 let x: f64 = 0.0000125;
675 let y: Option<Decimal> = x.checked_convert();
676 assert!(y.is_some());
677 let decimal = y.unwrap();
678 assert!(decimal.to_string().starts_with("0.0000125"));
680 }
683
684 #[test]
685 fn test_checked_convert_negative() {
686 let x: f64 = -9876.543210;
687 let y: Option<Decimal> = x.checked_convert();
688 assert!(y.is_some());
689 let decimal = y.unwrap();
690 assert!(decimal.to_string().starts_with("-9876.5432"));
692 }
693
694 #[test]
695 fn test_checked_convert_zero() {
696 let x: f64 = 0.0;
697 let y: Option<Decimal> = x.checked_convert();
698 assert!(y.is_some());
699 let decimal = y.unwrap();
700 assert_eq!(decimal.to_string(), "0");
701 }
702
703 #[test]
704 fn test_checked_convert_negative_zero() {
705 let x: f64 = -0.0;
706 let y: Option<Decimal> = x.checked_convert();
707 assert!(y.is_some());
708 let decimal = y.unwrap();
709 assert_eq!(decimal.to_string(), "0");
711 }
712
713 #[test]
714 fn test_checked_convert_nan() {
715 let x: f64 = f64::NAN;
716 let y: Option<Decimal> = x.checked_convert();
717 assert!(y.is_none());
718 }
719
720 #[test]
721 fn test_checked_convert_infinity() {
722 let x: f64 = f64::INFINITY;
723 let y: Option<Decimal> = x.checked_convert();
724 assert!(y.is_none());
725 }
726
727 #[test]
728 fn test_checked_convert_neg_infinity() {
729 let x: f64 = f64::NEG_INFINITY;
730 let y: Option<Decimal> = x.checked_convert();
731 assert!(y.is_none());
732 }
733
734 #[test]
735 fn test_saturating_convert() {
736 let x: f64 = 999999.999999;
737 let y: Decimal = x.saturating_convert();
738 let str_repr = y.to_string();
741 assert!(str_repr.starts_with("999999") || str_repr.starts_with("1000000"));
742 }
744
745 #[test]
746 fn test_saturating_convert_nan() {
747 let x: f64 = f64::NAN;
748 let y: Decimal = x.saturating_convert();
749 assert_eq!(y.to_string(), "0");
750 }
751
752 #[test]
753 fn test_saturating_convert_infinity() {
754 let x: f64 = f64::INFINITY;
755 let y: Decimal = x.saturating_convert();
756 assert_eq!(y.to_string(), "0");
757 }
758
759 #[test]
760 fn test_wrapping_convert() {
761 let x: f64 = 42.0;
762 let y: Decimal = x.wrapping_convert();
763 assert_eq!(y.to_string(), "42");
764 }
765
766 #[test]
767 fn test_wrapping_convert_with_decimal() {
768 let x: f64 = 3.14159;
769 let y: Decimal = x.wrapping_convert();
770 let str_repr = y.to_string();
772 assert!(str_repr.starts_with("3.141"), "actual: {}", str_repr);
774 }
775 }
776}