valu3/types/
number.rs

1//! A module to handle different number types, provide safe and unsafe access methods, and
2//! perform checks on number properties.
3//!
4//! The `Number` struct is used to store multiple numeric types, and provides various methods
5//! to set and retrieve these values safely and unsafely, as well as check their properties.
6//!
7//! The `NumberType` enum is used to identify the type of number stored in a `Number` instance.
8use crate::prelude::*;
9use std::fmt::Display;
10
11pub trait NumberBehavior {
12    /// Sets the value of the `Number` struct to the given `u8` value.
13    ///
14    /// # Arguments
15    ///
16    /// * `value` - A `u8` value to set in the `Number` struct.
17    ///
18    /// # Examples
19    ///
20    /// ```no_run
21    /// let mut num = Number::default();
22    /// num.set_u8(42);
23    /// ```
24    fn set_u8(&mut self, value: u8);
25    fn set_u16(&mut self, value: u16);
26    fn set_u32(&mut self, value: u32);
27    fn set_u64(&mut self, value: u64);
28    fn set_u128(&mut self, value: u128);
29    fn set_i8(&mut self, value: i8);
30    fn set_i16(&mut self, value: i16);
31    fn set_i32(&mut self, value: i32);
32    fn set_i64(&mut self, value: i64);
33    fn set_i128(&mut self, value: i128);
34    fn set_f32(&mut self, value: f32);
35    fn set_f64(&mut self, value: f64);
36
37    /// Returns the `u8` value stored in the `Number` struct, if any.
38    ///
39    /// # Returns
40    ///
41    /// An `Option<u8>` containing the stored `u8` value if it exists, or `None` otherwise.
42    ///
43    /// # Examples
44    ///
45    /// ```no_run
46    /// let mut num = Number::default();
47    /// num.set_u8(42);
48    /// assert_eq!(num.get_u8(), Some(42));
49    /// ```
50    fn get_u8(&self) -> Option<u8>;
51    fn get_u16(&self) -> Option<u16>;
52    fn get_u32(&self) -> Option<u32>;
53    fn get_u64(&self) -> Option<u64>;
54    fn get_u128(&self) -> Option<u128>;
55    fn get_i8(&self) -> Option<i8>;
56    fn get_i16(&self) -> Option<i16>;
57    fn get_i32(&self) -> Option<i32>;
58    fn get_i64(&self) -> Option<i64>;
59    fn get_i128(&self) -> Option<i128>;
60    fn get_f32(&self) -> Option<f32>;
61    fn get_f64(&self) -> Option<f64>;
62
63    /// Returns the `u8` value stored in the `Number` struct, without checking if it exists.
64    ///
65    /// # Safety
66    ///
67    /// This function is unsafe because it can return an incorrect value if a `u8` value is not
68    /// stored in the `Number` struct.
69    ///
70    /// # Examples
71    ///
72    /// ```no_run
73    /// let mut num = Number::default();
74    /// num.set_u8(42);
75    /// unsafe { assert_eq!(num.get_u8_unsafe(), 42) };
76    /// ```
77    fn get_u8_unsafe(&self) -> u8;
78    fn get_u16_unsafe(&self) -> u16;
79    fn get_u32_unsafe(&self) -> u32;
80    fn get_u64_unsafe(&self) -> u64;
81    fn get_u128_unsafe(&self) -> u128;
82    fn get_i8_unsafe(&self) -> i8;
83    fn get_i16_unsafe(&self) -> i16;
84    fn get_i32_unsafe(&self) -> i32;
85    fn get_i64_unsafe(&self) -> i64;
86    fn get_i128_unsafe(&self) -> i128;
87    fn get_f32_unsafe(&self) -> f32;
88    fn get_f64_unsafe(&self) -> f64;
89
90    /// Checks if the stored number is of type `i8`.
91    ///
92    /// # Returns
93    ///
94    /// `true` if the stored number is of type `i8`, `false` otherwise.
95    ///
96    /// # Examples
97    ///
98    /// ```no_run
99    /// let mut num = Number::default();
100    /// num.set_i8(-42);
101    /// assert_eq!(num.is_i8(), true);
102    /// ```
103    fn is_i8(&self) -> bool;
104    fn is_i16(&self) -> bool;
105    fn is_i32(&self) -> bool;
106    fn is_i64(&self) -> bool;
107    fn is_i128(&self) -> bool;
108    fn is_u8(&self) -> bool;
109    fn is_u16(&self) -> bool;
110    fn is_u32(&self) -> bool;
111    fn is_u64(&self) -> bool;
112    fn is_u128(&self) -> bool;
113    fn is_f32(&self) -> bool;
114    fn is_f64(&self) -> bool;
115
116    /// Checks if the `Number` struct contains any value.
117    ///
118    /// # Returns
119    ///
120    /// `true` if the `Number` struct contains a value, `false` otherwise.
121    ///
122    /// # Examples
123    ///
124    /// ```no_run
125    /// let num = Number::default();
126    /// assert_eq!(num.is_number(), false);
127    /// ```
128    fn is_number(&self) -> bool;
129    fn is_integer(&self) -> bool;
130    fn is_float(&self) -> bool;
131    fn is_signed(&self) -> bool;
132    fn is_unsigned(&self) -> bool;
133    fn is_zero(&self) -> bool;
134    fn is_positive(&self) -> bool;
135    fn is_negative(&self) -> bool;
136
137    /// fn is_integer(&self) -> bool { /* ... */ }
138    // ...
139
140    /// Determines the type of number stored in the `Number` struct.
141    ///
142    /// # Returns
143    ///
144    /// A `NumberType` variant representing the type of the stored number.
145    ///
146    /// # Examples
147    ///
148    /// ```no_run
149    /// let mut num = Number::default();
150    /// num.set_u32(42);
151    /// assert_eq!(num.number_type(), NumberType::U32);
152    /// ```
153    fn number_type(&self) -> NumberType;
154
155    /// Converts the `Number` struct to numeric types.
156    ///
157    /// # Returns
158    ///
159    /// An `Option` containing the converted numeric value if it exists, or `None` otherwise.
160    ///
161    /// # Examples
162    ///
163    /// ```no_run
164    /// let mut num = Number::default();
165    /// num.set_u32(42);
166    /// assert_eq!(num.to_i64(), Some(42));
167    /// ```
168    fn to_u64(&self) -> Option<u64>;
169    fn to_i64(&self) -> Option<i64>;
170    fn to_f64(&self) -> Option<f64>;
171}
172
173/// An enum representing different numeric types.
174#[derive(Debug, Clone, PartialEq)]
175pub enum NumberType {
176    U8,
177    U16,
178    U32,
179    U64,
180    U128,
181    I8,
182    I16,
183    I32,
184    I64,
185    I128,
186    F32,
187    F64,
188    Unknown,
189}
190
191/// A struct representing a number that can store different numeric types.
192///
193/// # Examples
194///
195/// ```
196/// let mut num = Number::default();
197/// num.set_u8(42);
198/// assert_eq!(num.get_u8(), Some(42));
199/// ```
200#[derive(Debug, Clone, PartialEq, Default, PartialOrd)]
201pub struct Number {
202    pub u8: Option<u8>,
203    pub u16: Option<u16>,
204    pub u32: Option<u32>,
205    pub u64: Option<u64>,
206    pub u128: Option<u128>,
207    pub i8: Option<i8>,
208    pub i16: Option<i16>,
209    pub i32: Option<i32>,
210    pub i64: Option<i64>,
211    pub i128: Option<i128>,
212    pub f32: Option<f32>,
213    pub f64: Option<f64>,
214}
215
216impl Number {
217    /// Empties the `Number` struct by removing any stored value.
218    ///
219    /// # Returns
220    ///
221    /// A mutable reference to the `Number` struct after removing any stored value.
222    ///
223    /// # Examples
224    ///
225    /// ```no_run
226    /// let mut num = Number::default();
227    /// num.set_u64(42);
228    /// num.clean();
229    /// assert_eq!(num.is_number(), false);
230    /// ```
231    pub fn clean(&mut self) -> &mut Self {
232        self.u8 = None;
233        self.u16 = None;
234        self.u32 = None;
235        self.u64 = None;
236        self.u128 = None;
237        self.i8 = None;
238        self.i16 = None;
239        self.i32 = None;
240        self.i64 = None;
241        self.i128 = None;
242        self.f32 = None;
243        self.f64 = None;
244        self
245    }
246}
247
248// Implementations of methods for setting and getting number values safely and unsafely,
249// as well as checking their properties and identifying the number type.
250impl NumberBehavior for Number {
251    fn set_u8(&mut self, value: u8) {
252        self.u8 = Some(value);
253    }
254
255    fn set_u16(&mut self, value: u16) {
256        self.u16 = Some(value);
257    }
258
259    fn set_u32(&mut self, value: u32) {
260        self.u32 = Some(value);
261    }
262
263    fn set_u64(&mut self, value: u64) {
264        self.u64 = Some(value);
265    }
266
267    fn set_u128(&mut self, value: u128) {
268        self.u128 = Some(value);
269    }
270
271    fn set_i8(&mut self, value: i8) {
272        self.i8 = Some(value);
273    }
274
275    fn set_i16(&mut self, value: i16) {
276        self.i16 = Some(value);
277    }
278
279    fn set_i32(&mut self, value: i32) {
280        self.i32 = Some(value);
281    }
282
283    fn set_i64(&mut self, value: i64) {
284        self.i64 = Some(value);
285    }
286
287    fn set_i128(&mut self, value: i128) {
288        self.i128 = Some(value);
289    }
290
291    fn set_f32(&mut self, value: f32) {
292        self.f32 = Some(value);
293    }
294
295    fn set_f64(&mut self, value: f64) {
296        self.f64 = Some(value);
297    }
298
299    fn get_u8(&self) -> Option<u8> {
300        self.u8
301    }
302
303    fn get_u16(&self) -> Option<u16> {
304        self.u16
305    }
306
307    fn get_u32(&self) -> Option<u32> {
308        self.u32
309    }
310
311    fn get_u64(&self) -> Option<u64> {
312        self.u64
313    }
314
315    fn get_u128(&self) -> Option<u128> {
316        self.u128
317    }
318
319    fn get_i8(&self) -> Option<i8> {
320        self.i8
321    }
322
323    fn get_i16(&self) -> Option<i16> {
324        self.i16
325    }
326
327    fn get_i32(&self) -> Option<i32> {
328        self.i32
329    }
330
331    fn get_i64(&self) -> Option<i64> {
332        self.i64
333    }
334
335    fn get_i128(&self) -> Option<i128> {
336        self.i128
337    }
338
339    fn get_f32(&self) -> Option<f32> {
340        self.f32
341    }
342
343    fn get_f64(&self) -> Option<f64> {
344        self.f64
345    }
346
347    fn get_u8_unsafe(&self) -> u8 {
348        self.u8.unwrap()
349    }
350
351    fn get_u16_unsafe(&self) -> u16 {
352        self.u16.unwrap()
353    }
354
355    fn get_u32_unsafe(&self) -> u32 {
356        self.u32.unwrap()
357    }
358
359    fn get_u64_unsafe(&self) -> u64 {
360        self.u64.unwrap()
361    }
362
363    fn get_u128_unsafe(&self) -> u128 {
364        self.u128.unwrap()
365    }
366
367    fn get_i8_unsafe(&self) -> i8 {
368        self.i8.unwrap()
369    }
370
371    fn get_i16_unsafe(&self) -> i16 {
372        self.i16.unwrap()
373    }
374
375    fn get_i32_unsafe(&self) -> i32 {
376        self.i32.unwrap()
377    }
378
379    fn get_i64_unsafe(&self) -> i64 {
380        self.i64.unwrap()
381    }
382
383    fn get_i128_unsafe(&self) -> i128 {
384        self.i128.unwrap()
385    }
386
387    fn get_f32_unsafe(&self) -> f32 {
388        self.f32.unwrap()
389    }
390
391    fn get_f64_unsafe(&self) -> f64 {
392        self.f64.unwrap()
393    }
394
395    fn is_i8(&self) -> bool {
396        self.i8.is_some()
397    }
398
399    fn is_i16(&self) -> bool {
400        self.i16.is_some()
401    }
402
403    fn is_i32(&self) -> bool {
404        self.i32.is_some()
405    }
406
407    fn is_i64(&self) -> bool {
408        self.i64.is_some()
409    }
410
411    fn is_i128(&self) -> bool {
412        self.i128.is_some()
413    }
414
415    fn is_u8(&self) -> bool {
416        self.u8.is_some()
417    }
418
419    fn is_u16(&self) -> bool {
420        self.u16.is_some()
421    }
422
423    fn is_u32(&self) -> bool {
424        self.u32.is_some()
425    }
426
427    fn is_u64(&self) -> bool {
428        self.u64.is_some()
429    }
430
431    fn is_u128(&self) -> bool {
432        self.u128.is_some()
433    }
434
435    fn is_f32(&self) -> bool {
436        self.f32.is_some()
437    }
438
439    fn is_f64(&self) -> bool {
440        self.f64.is_some()
441    }
442
443    fn is_number(&self) -> bool {
444        self.is_i8()
445            || self.is_i16()
446            || self.is_i32()
447            || self.is_i64()
448            || self.is_i128()
449            || self.is_u8()
450            || self.is_u16()
451            || self.is_u32()
452            || self.is_u64()
453            || self.is_u128()
454            || self.is_f32()
455            || self.is_f64()
456    }
457
458    /// Checks if the stored number is an integer.
459    ///
460    /// # Returns
461    ///
462    /// `true` if the stored number is an integer, `false` otherwise.
463    ///
464    /// # Examples
465    ///
466    /// ```no_run
467    /// let mut num = Number::default();
468    /// num.set_i32(42);
469    /// assert_eq!(num.is_integer(), true);
470    /// ```
471    fn is_integer(&self) -> bool {
472        self.is_i8()
473            || self.is_i16()
474            || self.is_i32()
475            || self.is_i64()
476            || self.is_i128()
477            || self.is_u8()
478            || self.is_u16()
479            || self.is_u32()
480            || self.is_u64()
481            || self.is_u128()
482    }
483
484    fn is_float(&self) -> bool {
485        self.is_f32() || self.is_f64()
486    }
487
488    fn is_signed(&self) -> bool {
489        self.is_i8() && self.i8.unwrap() < 0
490            || self.is_i16() && self.i16.unwrap() < 0
491            || self.is_i32() && self.i32.unwrap() < 0
492            || self.is_i64() && self.i64.unwrap() < 0
493            || self.is_i128() && self.i128.unwrap() < 0
494            || self.is_f32() && self.f32.unwrap() < 0.0
495            || self.is_f64() && self.f64.unwrap() < 0.0
496    }
497
498    fn is_unsigned(&self) -> bool {
499        self.is_u8() || self.is_u16() || self.is_u32() || self.is_u64() || self.is_u128()
500    }
501
502    fn is_zero(&self) -> bool {
503        self.is_i8() && self.i8.unwrap() == 0
504            || self.is_i16() && self.i16.unwrap() == 0
505            || self.is_i32() && self.i32.unwrap() == 0
506            || self.is_i64() && self.i64.unwrap() == 0
507            || self.is_i128() && self.i128.unwrap() == 0
508            || self.is_f32() && self.f32.unwrap() == 0.0
509            || self.is_f64() && self.f64.unwrap() == 0.0
510            || self.is_u8() && self.u8.unwrap() == 0
511            || self.is_u16() && self.u16.unwrap() == 0
512            || self.is_u32() && self.u32.unwrap() == 0
513            || self.is_u64() && self.u64.unwrap() == 0
514            || self.is_u128() && self.u128.unwrap() == 0
515    }
516
517    fn is_positive(&self) -> bool {
518        !self.is_signed() && !self.is_zero()
519    }
520
521    fn is_negative(&self) -> bool {
522        self.is_signed() && !self.is_zero()
523    }
524
525    fn number_type(&self) -> NumberType {
526        if self.is_i8() {
527            NumberType::I8
528        } else if self.is_i16() {
529            NumberType::I16
530        } else if self.is_i32() {
531            NumberType::I32
532        } else if self.is_i64() {
533            NumberType::I64
534        } else if self.is_i128() {
535            NumberType::I128
536        } else if self.is_u8() {
537            NumberType::U8
538        } else if self.is_u16() {
539            NumberType::U16
540        } else if self.is_u32() {
541            NumberType::U32
542        } else if self.is_u64() {
543            NumberType::U64
544        } else if self.is_u128() {
545            NumberType::U128
546        } else if self.is_f32() {
547            NumberType::F32
548        } else if self.is_f64() {
549            NumberType::F64
550        } else {
551            NumberType::Unknown
552        }
553    }
554
555    fn to_f64(&self) -> Option<f64> {
556        if self.is_f64() {
557            Some(self.get_f64_unsafe())
558        } else if self.is_f32() {
559            Some(self.get_f32_unsafe() as f64)
560        } else if self.is_i128() {
561            Some(self.get_i128_unsafe() as f64)
562        } else if self.is_i64() {
563            Some(self.get_i64_unsafe() as f64)
564        } else if self.is_i32() {
565            Some(self.get_i32_unsafe() as f64)
566        } else if self.is_i16() {
567            Some(self.get_i16_unsafe() as f64)
568        } else if self.is_i8() {
569            Some(self.get_i8_unsafe() as f64)
570        } else if self.is_u128() {
571            Some(self.get_u128_unsafe() as f64)
572        } else if self.is_u64() {
573            Some(self.get_u64_unsafe() as f64)
574        } else if self.is_u32() {
575            Some(self.get_u32_unsafe() as f64)
576        } else if self.is_u16() {
577            Some(self.get_u16_unsafe() as f64)
578        } else if self.is_u8() {
579            Some(self.get_u8_unsafe() as f64)
580        } else {
581            None
582        }
583    }
584
585    fn to_i64(&self) -> Option<i64> {
586        if self.is_i128() {
587            if self.get_i128_unsafe() > i64::MAX as i128 {
588                return None;
589            }
590
591            Some(self.get_i128_unsafe() as i64)
592        } else if self.is_i64() {
593            Some(self.get_i64_unsafe() as i64)
594        } else if self.is_i32() {
595            Some(self.get_i32_unsafe() as i64)
596        } else if self.is_i16() {
597            Some(self.get_i16_unsafe() as i64)
598        } else if self.is_i8() {
599            Some(self.get_i8_unsafe() as i64)
600        } else if self.is_u128() {
601            if self.get_u128_unsafe() > i64::MAX as u128 {
602                return None;
603            }
604
605            Some(self.get_u128_unsafe() as i64)
606        } else if self.is_u64() {
607            Some(self.get_u64_unsafe() as i64)
608        } else if self.is_u32() {
609            Some(self.get_u32_unsafe() as i64)
610        } else if self.is_u16() {
611            Some(self.get_u16_unsafe() as i64)
612        } else if self.is_u8() {
613            Some(self.get_u8_unsafe() as i64)
614        } else {
615            None
616        }
617    }
618
619    fn to_u64(&self) -> Option<u64> {
620        if self.is_i128() {
621            if self.get_i128_unsafe() < 0 || self.get_i128_unsafe() > u64::MAX as i128 {
622                return None;
623            }
624
625            Some(self.get_i128_unsafe() as u64)
626        } else if self.is_i64() {
627            if self.get_i64_unsafe() < 0 {
628                return None;
629            }
630
631            Some(self.get_i64_unsafe() as u64)
632        } else if self.is_i32() {
633            if self.get_i32_unsafe() < 0 {
634                return None;
635            }
636
637            Some(self.get_i32_unsafe() as u64)
638        } else if self.is_i16() {
639            if self.get_i16_unsafe() < 0 {
640                return None;
641            }
642
643            Some(self.get_i16_unsafe() as u64)
644        } else if self.is_i8() {
645            if self.get_i8_unsafe() < 0 {
646                return None;
647            }
648
649            Some(self.get_i8_unsafe() as u64)
650        } else if self.is_u128() {
651            if self.get_u128_unsafe() > u64::MAX as u128 {
652                return None;
653            }
654
655            Some(self.get_u128_unsafe() as u64)
656        } else if self.is_u64() {
657            Some(self.get_u64_unsafe() as u64)
658        } else if self.is_u32() {
659            Some(self.get_u32_unsafe() as u64)
660        } else if self.is_u16() {
661            Some(self.get_u16_unsafe() as u64)
662        } else if self.is_u8() {
663            Some(self.get_u8_unsafe() as u64)
664        } else {
665            None
666        }
667    }
668}
669
670/// Implements the `Display` trait for the `Number` struct.
671///
672/// Provides a human-readable representation of a `Number` instance
673/// by matching its fields and converting the value to a string.
674impl Display for Number {
675    /// Formats the `Number` struct for display by returning a string representation of the stored value.
676    ///
677    /// # Arguments
678    ///
679    /// * `f` - A mutable reference to a `std::fmt::Formatter` used for formatting the display.
680    ///
681    /// # Returns
682    ///
683    /// A `std::fmt::Result` containing the result of the formatting operation.
684    ///
685    /// # Examples
686    ///
687    /// ```no_run
688    /// let mut num = Number::default();
689    /// num.set_f64(42.0);
690    /// println!("{}", num); // Output: 42.0
691    /// ```
692    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
693        if self.is_i8() {
694            write!(f, "{}", self.get_i8_unsafe())
695        } else if self.is_i16() {
696            write!(f, "{}", self.get_i16_unsafe())
697        } else if self.is_i32() {
698            write!(f, "{}", self.get_i32_unsafe())
699        } else if self.is_i64() {
700            write!(f, "{}", self.get_i64_unsafe())
701        } else if self.is_i128() {
702            write!(f, "{}", self.get_i128_unsafe())
703        } else if self.is_u8() {
704            write!(f, "{}", self.get_u8_unsafe())
705        } else if self.is_u16() {
706            write!(f, "{}", self.get_u16_unsafe())
707        } else if self.is_u32() {
708            write!(f, "{}", self.get_u32_unsafe())
709        } else if self.is_u64() {
710            write!(f, "{}", self.get_u64_unsafe())
711        } else if self.is_u128() {
712            write!(f, "{}", self.get_u128_unsafe())
713        } else if self.is_f32() {
714            write!(f, "{}", self.get_f32_unsafe())
715        } else if self.is_f64() {
716            write!(f, "{}", self.get_f64_unsafe())
717        } else {
718            write!(f, "0")
719        }
720    }
721}
722
723// Implementations of the `From` trait for integer, unsigned integer, and floating-point types
724// that allow for easy conversion of these types into a `Number`.
725
726/// Converts an `i8` value to a `Number`.
727impl From<i8> for Number {
728    fn from(i: i8) -> Self {
729        Number {
730            i8: Some(i),
731            ..Default::default()
732        }
733    }
734}
735
736/// Converts an `i16` value to a `Number`.
737impl From<i16> for Number {
738    fn from(i: i16) -> Self {
739        Number {
740            i16: Some(i),
741            ..Default::default()
742        }
743    }
744}
745
746/// Converts an `i32` value to a `Number`.
747impl From<i32> for Number {
748    fn from(i: i32) -> Self {
749        Number {
750            i32: Some(i),
751            ..Default::default()
752        }
753    }
754}
755
756/// Converts an `i64` value to a `Number`.
757impl From<i64> for Number {
758    fn from(i: i64) -> Self {
759        Number {
760            i64: Some(i),
761            ..Default::default()
762        }
763    }
764}
765
766/// Converts an `i128` value to a `Number`.
767impl From<i128> for Number {
768    fn from(i: i128) -> Self {
769        Number {
770            i128: Some(i),
771            ..Default::default()
772        }
773    }
774}
775
776/// Converts an `u8` value to a `Number`.
777impl From<u8> for Number {
778    fn from(i: u8) -> Self {
779        Number {
780            u8: Some(i),
781            ..Default::default()
782        }
783    }
784}
785
786/// Converts an `u16` value to a `Number`.
787impl From<u16> for Number {
788    fn from(i: u16) -> Self {
789        Number {
790            u16: Some(i),
791            ..Default::default()
792        }
793    }
794}
795
796/// Converts an `u32` value to a `Number`.
797impl From<u32> for Number {
798    fn from(i: u32) -> Self {
799        Number {
800            u32: Some(i),
801            ..Default::default()
802        }
803    }
804}
805
806/// Converts an `u8` value to a `Number`.
807impl From<u64> for Number {
808    fn from(i: u64) -> Self {
809        Number {
810            u64: Some(i),
811            ..Default::default()
812        }
813    }
814}
815
816/// Converts an `u128` value to a `Number`.
817impl From<u128> for Number {
818    fn from(i: u128) -> Self {
819        Number {
820            u128: Some(i),
821            ..Default::default()
822        }
823    }
824}
825
826/// Converts an `f32` value to a `Number`.
827impl From<f32> for Number {
828    fn from(i: f32) -> Self {
829        Number {
830            f32: Some(i),
831            ..Default::default()
832        }
833    }
834}
835
836/// Converts an `f64` value to a `Number`.
837impl From<f64> for Number {
838    fn from(i: f64) -> Self {
839        Number {
840            f64: Some(i),
841            ..Default::default()
842        }
843    }
844}
845
846/// Converts an `usize` value to a `Number`.
847impl From<usize> for Number {
848    fn from(i: usize) -> Self {
849        match i {
850            i if i <= u8::MAX as usize => Number::from(i as u8),
851            i if i <= u16::MAX as usize => Number::from(i as u16),
852            i if i <= u32::MAX as usize => Number::from(i as u32),
853            i if i <= u64::MAX as usize => Number::from(i as u64),
854            i if i <= u128::MAX as usize => Number::from(i as u128),
855            i if i <= i8::MAX as usize => Number::from(i as i8),
856            i if i <= i16::MAX as usize => Number::from(i as i16),
857            i if i <= i32::MAX as usize => Number::from(i as i32),
858            i if i <= i64::MAX as usize => Number::from(i as i64),
859            i if i <= i128::MAX as usize => Number::from(i as i128),
860            i if i <= f32::MAX as usize => Number::from(i as f32),
861            i if i <= f64::MAX as usize => Number::from(i as f64),
862            _ => Number::from(i as f64),
863        }
864    }
865}
866
867impl From<isize> for Number {
868    fn from(i: isize) -> Self {
869        match i {
870            i if i <= i8::MAX as isize => Number::from(i as i8),
871            i if i <= i16::MAX as isize => Number::from(i as i16),
872            i if i <= i32::MAX as isize => Number::from(i as i32),
873            i if i <= i64::MAX as isize => Number::from(i as i64),
874            i if i <= i128::MAX as isize => Number::from(i as i128),
875            i if i <= f32::MAX as isize => Number::from(i as f32),
876            i if i <= f64::MAX as isize => Number::from(i as f64),
877            _ => Number::from(i as f64),
878        }
879    }
880}
881
882/// Converts a `&str` value to a `Number` if it can be parsed as a valid number.
883///
884/// # Arguments
885///
886/// * `value` - A string slice containing a numeric value to be converted.
887///
888/// # Returns
889///
890/// A `Result<Self, Self::Error>` containing the `Number` if the conversion was successful
891/// or an error if the conversion failed.
892///
893/// # Examples
894///
895/// ```
896/// let num = Number::try_from("42").unwrap();
897/// assert_eq!(num.get_i32(), Some(42));
898///
899/// let num = Number::try_from("42.0").unwrap();
900/// assert_eq!(num.get_f64(), Some(42.0));
901///
902/// let num = Number::try_from("invalid");
903/// assert!(num.is_err());
904/// ```
905impl TryFrom<&str> for Number {
906    type Error = Error;
907
908    fn try_from(value: &str) -> Result<Self, Self::Error> {
909        if let Ok(parsed) = value.parse::<i32>() {
910            return Ok(Self::from(parsed));
911        }
912        if let Ok(parsed) = value.parse::<f64>() {
913            return Ok(Self::from(parsed));
914        }
915        if let Ok(parsed) = value.parse::<i8>() {
916            return Ok(Self::from(parsed));
917        }
918        if let Ok(parsed) = value.parse::<i16>() {
919            return Ok(Self::from(parsed));
920        }
921        if let Ok(parsed) = value.parse::<i64>() {
922            return Ok(Self::from(parsed));
923        }
924        if let Ok(parsed) = value.parse::<i128>() {
925            return Ok(Self::from(parsed));
926        }
927        if let Ok(parsed) = value.parse::<u8>() {
928            return Ok(Self::from(parsed));
929        }
930        if let Ok(parsed) = value.parse::<u16>() {
931            return Ok(Self::from(parsed));
932        }
933        if let Ok(parsed) = value.parse::<u32>() {
934            return Ok(Self::from(parsed));
935        }
936        if let Ok(parsed) = value.parse::<u64>() {
937            return Ok(Self::from(parsed));
938        }
939        if let Ok(parsed) = value.parse::<u128>() {
940            return Ok(Self::from(parsed));
941        }
942        if let Ok(parsed) = value.parse::<f32>() {
943            return Ok(Self::from(parsed));
944        }
945        Err(Error::NotNumber)
946    }
947}
948
949/// Converts a `String` value to a `Number` if it can be parsed as a valid number.
950///
951/// # Arguments
952///
953/// * `value` - A `String` containing a numeric value to be converted.
954///
955/// # Returns
956///
957/// A `Result<Self, Self::Error>` containing the `Number` if the conversion was successful
958/// or an error if the conversion failed.
959///
960/// # Examples
961///
962/// ```
963/// let num = Number::try_from("42".to_string()).unwrap();
964/// assert_eq!(num.get_i32(), Some(42));
965///
966/// let num = Number::try_from("42.0".to_string()).unwrap();
967/// assert_eq!(num.get_f64(), Some(42.0));
968///
969/// let num = Number::try_from("invalid".to_string());
970/// assert!(num.is_err());
971/// ```
972impl TryFrom<String> for Number {
973    type Error = Error;
974
975    fn try_from(value: String) -> Result<Self, Self::Error> {
976        Self::try_from(value.as_str())
977    }
978}
979
980#[cfg(test)]
981mod tests {
982    use crate::prelude::*;
983
984    #[test]
985    fn test_setters_and_getters() {
986        let mut number = Number::default();
987
988        number.clean().set_u8(42);
989        assert_eq!(number.get_u8(), Some(42));
990
991        number.clean().set_u16(12345);
992        assert_eq!(number.get_u16(), Some(12345));
993
994        number.clean().set_u32(12345678);
995        assert_eq!(number.get_u32(), Some(12345678));
996
997        number.clean().set_u64(12345678901234);
998        assert_eq!(number.get_u64(), Some(12345678901234));
999
1000        number.clean().set_u128(123456789012345678901234567890);
1001        assert_eq!(number.get_u128(), Some(123456789012345678901234567890));
1002
1003        number.clean().set_i8(-42);
1004        assert_eq!(number.get_i8(), Some(-42));
1005
1006        number.clean().set_i16(-12345);
1007        assert_eq!(number.get_i16(), Some(-12345));
1008
1009        number.clean().set_i32(-12345678);
1010        assert_eq!(number.get_i32(), Some(-12345678));
1011
1012        number.clean().set_i64(-12345678901234);
1013        assert_eq!(number.get_i64(), Some(-12345678901234));
1014
1015        number.clean().set_i128(-123456789012345678901234567890);
1016        assert_eq!(number.get_i128(), Some(-123456789012345678901234567890));
1017
1018        number.clean().set_f32(3.14);
1019        assert_eq!(number.get_f32(), Some(3.14));
1020
1021        number.clean().set_f64(6.283185307179586);
1022        assert_eq!(number.get_f64(), Some(6.283185307179586));
1023    }
1024
1025    #[test]
1026    fn test_display() {
1027        let mut number = Number::default();
1028
1029        number.clean().set_u8(42);
1030        assert_eq!(format!("{}", number), "42");
1031
1032        number.clean().set_i32(-12345678);
1033        assert_eq!(format!("{}", number), "-12345678");
1034
1035        number.clean().set_f32(3.14);
1036        assert_eq!(format!("{}", number), "3.14");
1037
1038        number.clean().set_u128(123456789012345678901234567890);
1039        assert_eq!(format!("{}", number), "123456789012345678901234567890");
1040    }
1041
1042    #[test]
1043    fn test_type_checkers() {
1044        let mut number = Number::default();
1045
1046        number.clean().set_u8(42);
1047        assert!(number.is_u8());
1048        assert!(number.is_integer());
1049        assert!(!number.is_float());
1050        assert!(!number.is_signed());
1051        assert!(number.is_unsigned());
1052        assert!(!number.is_zero());
1053        assert!(number.is_positive());
1054        assert!(!number.is_negative());
1055
1056        number.clean().set_i32(-12345678);
1057        assert!(number.is_i32());
1058        assert!(number.is_integer());
1059        assert!(!number.is_float());
1060        assert!(number.is_signed());
1061        assert!(!number.is_unsigned());
1062        assert!(!number.is_zero());
1063        assert!(!number.is_positive());
1064        assert!(number.is_negative());
1065
1066        number.clean().set_f32(0.0);
1067        assert!(number.is_f32());
1068        assert!(!number.is_integer());
1069        assert!(number.is_float());
1070        assert!(!number.is_signed());
1071        assert!(!number.is_unsigned());
1072        assert!(number.is_zero());
1073    }
1074
1075    #[test]
1076    fn test_set_and_get() {
1077        let mut number = Number::default();
1078
1079        number.clean().set_u8(42);
1080        assert_eq!(number.get_u8(), Some(42));
1081
1082        number.clean().set_u16(42);
1083        assert_eq!(number.get_u16(), Some(42));
1084
1085        number.clean().set_u32(42);
1086        assert_eq!(number.get_u32(), Some(42));
1087
1088        number.clean().set_u64(42);
1089        assert_eq!(number.get_u64(), Some(42));
1090
1091        number.clean().set_u128(42);
1092        assert_eq!(number.get_u128(), Some(42));
1093
1094        number.clean().set_i8(-42);
1095        assert_eq!(number.get_i8(), Some(-42));
1096
1097        number.clean().set_i16(-42);
1098        assert_eq!(number.get_i16(), Some(-42));
1099
1100        number.clean().set_i32(-42);
1101        assert_eq!(number.get_i32(), Some(-42));
1102
1103        number.clean().set_i64(-42);
1104        assert_eq!(number.get_i64(), Some(-42));
1105
1106        number.clean().set_i128(-42);
1107        assert_eq!(number.get_i128(), Some(-42));
1108
1109        number.clean().set_f32(-42.0);
1110        assert_eq!(number.get_f32(), Some(-42.0));
1111
1112        number.clean().set_f64(-42.0);
1113        assert_eq!(number.get_f64(), Some(-42.0));
1114    }
1115
1116    #[test]
1117    fn test_is_methods() {
1118        let mut number = Number::default();
1119
1120        number.clean().set_u8(42);
1121        assert!(number.is_u8());
1122
1123        number.clean().set_u16(42);
1124        assert!(number.is_u16());
1125
1126        number.clean().set_u32(42);
1127        assert!(number.is_u32());
1128
1129        number.clean().set_u64(42);
1130        assert!(number.is_u64());
1131
1132        number.clean().set_u128(42);
1133        assert!(number.is_u128());
1134
1135        number.clean().set_i8(-42);
1136        assert!(number.is_i8());
1137
1138        number.clean().set_i16(-42);
1139        assert!(number.is_i16());
1140
1141        number.clean().set_i32(-42);
1142        assert!(number.is_i32());
1143
1144        number.clean().set_i64(-42);
1145        assert!(number.is_i64());
1146
1147        number.clean().set_i128(-42);
1148        assert!(number.is_i128());
1149
1150        number.clean().set_f32(-42.0);
1151        assert!(number.is_f32());
1152
1153        number.clean().set_f64(-42.0);
1154        assert!(number.is_f64());
1155    }
1156
1157    #[test]
1158    fn test_number_type() {
1159        let mut number = Number::default();
1160
1161        number.clean().set_u8(10);
1162        assert_eq!(number.number_type(), NumberType::U8);
1163
1164        number.clean().set_u16(10_000);
1165        assert_eq!(number.number_type(), NumberType::U16);
1166
1167        number.clean().set_u32(1_000_000);
1168        assert_eq!(number.number_type(), NumberType::U32);
1169
1170        number.clean().set_u64(10_000_000_000);
1171        assert_eq!(number.number_type(), NumberType::U64);
1172
1173        number.clean().set_u128(100_000_000_000_000_000_000);
1174        assert_eq!(number.number_type(), NumberType::U128);
1175
1176        number.clean().set_i8(-42);
1177        assert_eq!(number.number_type(), NumberType::I8);
1178
1179        number.clean().set_i16(-12345);
1180        assert_eq!(number.number_type(), NumberType::I16);
1181
1182        number.clean().set_i32(-1_000_000);
1183        assert_eq!(number.number_type(), NumberType::I32);
1184
1185        number.clean().set_i64(-10_000_000_000);
1186        assert_eq!(number.number_type(), NumberType::I64);
1187
1188        number.clean().set_i128(-100_000_000_000_000_000_000);
1189        assert_eq!(number.number_type(), NumberType::I128);
1190
1191        number.clean().set_f32(-1_000_000.0);
1192        assert_eq!(number.number_type(), NumberType::F32);
1193
1194        number.clean().set_f64(-10_000_000_000.0);
1195        assert_eq!(number.number_type(), NumberType::F64);
1196    }
1197
1198    #[test]
1199    fn test_from_usize() {
1200        let number = Number::from(42usize);
1201        assert_eq!(number.get_u8(), Some(42));
1202    }
1203
1204    #[test]
1205    fn test_from_isize() {
1206        let number = Number::from(-42isize);
1207        assert_eq!(number.get_i8(), Some(-42));
1208    }
1209
1210    #[test]
1211    fn test_convert_number_to_f64() {
1212        let mut number = Number::default();
1213
1214        number.clean().set_u8(42);
1215        assert_eq!(number.to_f64(), Some(42.0f64));
1216
1217        number.clean().set_i32(-42);
1218        assert_eq!(number.to_f64(), Some(-42.0f64));
1219
1220        number.clean().set_f32(3.14);
1221        assert_eq!(number.to_f64(), Some(3.140000104904175f64)); // Floating-point precision issue
1222
1223        number.clean().set_u128(123456789012345678901234567890);
1224        assert_eq!(number.to_f64(), Some(123456789012345678901234567890.0));
1225    }
1226
1227    #[test]
1228    fn test_convert_number_to_i64() {
1229        let mut number = Number::default();
1230
1231        number.clean().set_i32(-42);
1232        assert_eq!(number.to_i64(), Some(-42));
1233
1234        number.clean().set_i128(-42);
1235        assert_eq!(number.to_i64(), Some(-42));
1236
1237        number.clean().set_f32(3.14);
1238        assert_eq!(number.to_i64(), None);
1239
1240        number.clean().set_u128(123456789012345678901234567890);
1241        assert_eq!(number.to_i64(), None);
1242
1243        number.clean().set_i128(i128::MAX);
1244        assert_eq!(number.to_i64(), None);
1245    }
1246
1247    #[test]
1248    fn test_convert_number_to_u64() {
1249        let mut number = Number::default();
1250
1251        number.clean().set_u32(42);
1252        assert_eq!(number.to_u64(), Some(42));
1253
1254        number.clean().set_u128(42);
1255        assert_eq!(number.to_u64(), Some(42));
1256
1257        number.clean().set_f32(3.14);
1258        assert_eq!(number.to_u64(), None);
1259
1260        number.clean().set_i128(-42);
1261        assert_eq!(number.to_u64(), None);
1262
1263        number.clean().set_u128(u128::MAX);
1264        assert_eq!(number.to_u64(), None);
1265    }
1266}