number_general/
lib.rs

1//! Provides a generic [`Number`] enum with [`Boolean`], [`Complex`], [`Float`], [`Int`],
2//! and [`UInt`] variants, as well as a [`NumberCollator`], [`ComplexCollator`], and
3//! [`FloatCollator`] since these types do not implement [`Ord`].
4//!
5//! `Number` supports casting with [`safecast`].
6//!
7//! For (de)serialization with `serde`, enable the `"serde"` feature.
8//!
9//! For (de)coding with `destream`, enable the `"stream"` feature.
10//!
11//! Example usage:
12//! ```
13//! # use number_general::{Int, Number};
14//! # use safecast::CastFrom;
15//! let sequence: Vec<Number> = vec![true.into(), 2.into(), 3.5.into(), [1.0, -0.5].into()];
16//! let actual = sequence.into_iter().product();
17//! let expected = Number::from(num::Complex::<f64>::new(7., -3.5));
18//!
19//! assert_eq!(expected, actual);
20//! assert_eq!(Int::cast_from(actual), Int::from(7));
21//! ```
22
23use std::cmp::Ordering;
24use std::fmt;
25use std::iter::{Product, Sum};
26use std::ops::*;
27use std::str::FromStr;
28
29use collate::{Collate, Collator};
30use get_size::GetSize;
31use get_size_derive::*;
32use safecast::{CastFrom, CastInto};
33
34mod class;
35#[cfg(feature = "stream")]
36mod destream;
37#[cfg(feature = "hash")]
38mod hash;
39mod instance;
40#[cfg(feature = "serde")]
41mod serde;
42
43pub use class::*;
44pub use instance::*;
45
46#[cfg(any(feature = "serde", feature = "stream"))]
47const ERR_COMPLEX: &str = "a complex number";
48
49#[cfg(any(feature = "serde", feature = "stream"))]
50const ERR_NUMBER: &str = "a Number, like 1 or -2 or 3.14 or [0., -1.414]";
51
52/// Define a [`NumberType`] for a non-[`Number`] type such as a Rust primitive.
53///
54/// To access the `NumberType` of a `Number`, use `Instance::class`, e.g. `Number::from(1).class()`.
55pub trait DType {
56    fn dtype() -> NumberType;
57}
58
59macro_rules! dtype {
60    ($t:ty, $nt:expr) => {
61        impl DType for $t {
62            fn dtype() -> NumberType {
63                $nt
64            }
65        }
66    };
67}
68
69dtype!(bool, NumberType::Bool);
70dtype!(u8, NumberType::UInt(UIntType::U8));
71dtype!(u16, NumberType::UInt(UIntType::U16));
72dtype!(u32, NumberType::UInt(UIntType::U32));
73dtype!(u64, NumberType::UInt(UIntType::U64));
74dtype!(i8, NumberType::Int(IntType::I8));
75dtype!(i16, NumberType::Int(IntType::I16));
76dtype!(i32, NumberType::Int(IntType::I32));
77dtype!(i64, NumberType::Int(IntType::I64));
78dtype!(f32, NumberType::Float(FloatType::F32));
79dtype!(f64, NumberType::Float(FloatType::F64));
80dtype!(_Complex<f32>, NumberType::Complex(ComplexType::C32));
81dtype!(_Complex<f64>, NumberType::Complex(ComplexType::C64));
82
83/// The error type returned when a `Number` operation fails recoverably.
84pub struct Error(String);
85
86impl Error {
87    fn new<E: fmt::Display>(cause: E) -> Self {
88        Self(cause.to_string())
89    }
90}
91
92impl std::error::Error for Error {}
93
94impl fmt::Debug for Error {
95    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96        f.write_str(&self.0)
97    }
98}
99
100impl fmt::Display for Error {
101    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102        f.write_str(&self.0)
103    }
104}
105
106type _Complex<T> = num::complex::Complex<T>;
107
108/// A generic number.
109#[derive(Clone, Copy, Eq, Hash, GetSize)]
110pub enum Number {
111    Bool(Boolean),
112    Complex(Complex),
113    Float(Float),
114    Int(Int),
115    UInt(UInt),
116}
117
118impl Number {
119    /// Return `true` if this is floating-point [`Number`], `false` if this is an integer.
120    pub fn is_float(&self) -> bool {
121        match self {
122            Self::Complex(_) => true,
123            Self::Float(_) => true,
124            _ => false,
125        }
126    }
127
128    /// Return `true` if this is an [`Int`] or [`UInt`].
129    pub fn is_int(&self) -> bool {
130        match self {
131            Self::Int(_) => true,
132            Self::UInt(_) => true,
133            _ => false,
134        }
135    }
136
137    /// Return `false` if this is a [`Complex`] `Number`.
138    pub fn is_real(&self) -> bool {
139        if let Self::Complex(_) = self {
140            false
141        } else {
142            true
143        }
144    }
145}
146
147impl NumberInstance for Number {
148    type Abs = Number;
149    type Exp = Self;
150    type Log = Self;
151    type Round = Self;
152    type Class = NumberType;
153
154    fn class(&self) -> NumberType {
155        match self {
156            Self::Bool(_) => NumberType::Bool,
157            Self::Complex(c) => c.class().into(),
158            Self::Float(f) => f.class().into(),
159            Self::Int(i) => i.class().into(),
160            Self::UInt(u) => u.class().into(),
161        }
162    }
163
164    fn into_type(self, dtype: NumberType) -> Number {
165        use NumberType as NT;
166
167        match dtype {
168            NT::Bool => {
169                let b: Boolean = self.cast_into();
170                b.into()
171            }
172            NT::Complex(ct) => {
173                let c: Complex = self.cast_into();
174                c.into_type(ct).into()
175            }
176            NT::Float(ft) => {
177                let f: Float = self.cast_into();
178                f.into_type(ft).into()
179            }
180            NT::Int(it) => {
181                let i: Int = self.cast_into();
182                i.into_type(it).into()
183            }
184            NT::UInt(ut) => {
185                let u: UInt = self.cast_into();
186                u.into_type(ut).into()
187            }
188            NT::Number => self,
189        }
190    }
191
192    fn abs(self) -> Number {
193        use Number::*;
194        match self {
195            Complex(c) => Float(c.abs()),
196            Float(f) => Float(f.abs()),
197            Int(i) => Int(i.abs()),
198            other => other,
199        }
200    }
201
202    fn exp(self) -> Self::Exp {
203        match self {
204            Self::Complex(this) => this.exp().into(),
205            Self::Float(this) => this.exp().into(),
206            this => Float::cast_from(this).exp().into(),
207        }
208    }
209
210    fn ln(self) -> Self::Log {
211        match self {
212            Self::Bool(b) => b.ln().into(),
213            Self::Complex(this) => this.ln().into(),
214            Self::Float(this) => this.ln().into(),
215            Self::Int(this) => this.ln().into(),
216            Self::UInt(this) => this.ln().into(),
217        }
218    }
219
220    fn log<N: NumberInstance>(self, base: N) -> Self::Log
221    where
222        Float: From<N>,
223    {
224        match self {
225            Self::Complex(this) => this.log(base).into(),
226            Self::Float(this) => this.log(base).into(),
227            this => Float::cast_from(this).log(base).into(),
228        }
229    }
230
231    fn pow(self, exp: Self) -> Self {
232        match self {
233            Self::Complex(this) => Self::Complex(this.pow(exp)),
234            Self::Float(this) => Self::Float(this.pow(exp)),
235            Self::Int(this) => match exp {
236                Self::Complex(exp) => Self::Float(Float::from(this).pow(exp.into())),
237                Self::Float(exp) => Self::Float(Float::from(this).pow(exp.into())),
238                Self::Int(exp) if exp < exp.class().zero() => {
239                    Self::Float(Float::from(this).pow(exp.into()))
240                }
241                exp => Self::Int(this.pow(exp)),
242            },
243            Self::UInt(this) => match exp {
244                Self::Complex(exp) => Self::Float(Float::from(this).pow(exp.into())),
245                Self::Float(exp) => Self::Float(Float::from(this).pow(exp.into())),
246                Self::Int(exp) if exp < exp.class().zero() => {
247                    Self::Float(Float::from(this).pow(exp.into()))
248                }
249                exp => Self::UInt(this.pow(exp)),
250            },
251            Self::Bool(b) => Self::Bool(b.pow(exp)),
252        }
253    }
254
255    fn round(self) -> Self::Round {
256        match self {
257            Self::Complex(c) => c.round().into(),
258            Self::Float(f) => f.round().into(),
259            other => other,
260        }
261    }
262}
263
264impl FloatInstance for Number {
265    fn is_infinite(&self) -> bool {
266        match self {
267            Self::Complex(c) => c.is_infinite(),
268            Self::Float(f) => f.is_infinite(),
269            _ => false,
270        }
271    }
272
273    fn is_nan(&self) -> bool {
274        match self {
275            Self::Complex(c) => c.is_nan(),
276            Self::Float(f) => f.is_nan(),
277            _ => false,
278        }
279    }
280}
281
282impl PartialEq for Number {
283    fn eq(&self, other: &Self) -> bool {
284        match (self, other) {
285            (Self::Int(l), Self::Int(r)) => l.eq(r),
286            (Self::UInt(l), Self::UInt(r)) => l.eq(r),
287            (Self::Float(l), Self::Float(r)) => l.eq(r),
288            (Self::Bool(l), Self::Bool(r)) => l.eq(r),
289            (Self::Complex(l), Self::Complex(r)) => l.eq(r),
290
291            (Self::Complex(l), r) => l.eq(&Complex::cast_from(*r)),
292            (Self::Float(l), r) => l.eq(&Float::cast_from(*r)),
293            (Self::Int(l), r) => l.eq(&Int::cast_from(*r)),
294            (Self::UInt(l), r) => l.eq(&UInt::cast_from(*r)),
295
296            (l, r) => r.eq(l),
297        }
298    }
299}
300
301impl PartialOrd for Number {
302    fn partial_cmp(&self, other: &Number) -> Option<Ordering> {
303        match (self, other) {
304            (Self::Int(l), Self::Int(r)) => l.partial_cmp(r),
305            (Self::UInt(l), Self::UInt(r)) => l.partial_cmp(r),
306            (Self::Float(l), Self::Float(r)) => l.partial_cmp(r),
307            (Self::Bool(l), Self::Bool(r)) => l.partial_cmp(r),
308            (Self::Complex(_), _) => None,
309            (_, Self::Complex(_)) => None,
310
311            (l, r) => {
312                let dtype = Ord::max(l.class(), r.class());
313                let l = l.into_type(dtype);
314                let r = r.into_type(dtype);
315                l.partial_cmp(&r)
316            }
317        }
318    }
319}
320
321impl Add for Number {
322    type Output = Self;
323
324    fn add(self, other: Number) -> Self {
325        let dtype = Ord::max(self.class(), other.class());
326
327        use NumberType as NT;
328
329        match dtype {
330            NT::Bool => {
331                let this: Boolean = self.cast_into();
332                (this + other.cast_into()).into()
333            }
334            NT::Complex(_) => {
335                let this: Complex = self.cast_into();
336                (this + other.cast_into()).into()
337            }
338            NT::Float(_) => {
339                let this: Float = self.cast_into();
340                (this + other.cast_into()).into()
341            }
342            NT::Int(_) => {
343                let this: Int = self.cast_into();
344                (this + other.cast_into()).into()
345            }
346            NT::UInt(_) => {
347                let this: UInt = self.cast_into();
348                (this + other.cast_into()).into()
349            }
350            NT::Number => panic!("A number instance must have a specific type, not Number"),
351        }
352    }
353}
354
355impl AddAssign for Number {
356    fn add_assign(&mut self, other: Self) {
357        let sum = *self + other;
358        *self = sum;
359    }
360}
361
362impl Rem for Number {
363    type Output = Self;
364
365    fn rem(self, other: Self) -> Self::Output {
366        let dtype = Ord::max(self.class(), other.class());
367
368        use NumberType as NT;
369
370        match dtype {
371            NT::Bool => {
372                let this: Boolean = self.cast_into();
373                (this % other.cast_into()).into()
374            }
375            NT::Complex(_) => {
376                let this: Complex = self.cast_into();
377                (this % other.cast_into()).into()
378            }
379            NT::Float(_) => {
380                let this: Float = self.cast_into();
381                (this % other.cast_into()).into()
382            }
383            NT::Int(_) => {
384                let this: Int = self.cast_into();
385                (this % other.cast_into()).into()
386            }
387            NT::UInt(_) => {
388                let this: UInt = self.cast_into();
389                (this % other.cast_into()).into()
390            }
391            NT::Number => panic!("A number instance must have a specific type, not Number"),
392        }
393    }
394}
395
396impl RemAssign for Number {
397    fn rem_assign(&mut self, other: Self) {
398        let rem = *self % other;
399        *self = rem;
400    }
401}
402
403impl Sub for Number {
404    type Output = Self;
405
406    fn sub(self, other: Number) -> Self {
407        let dtype = Ord::max(self.class(), other.class());
408
409        use NumberType as NT;
410
411        match dtype {
412            NT::Bool => {
413                let this: Boolean = self.cast_into();
414                (this - other.cast_into()).into()
415            }
416            NT::Complex(_) => {
417                let this: Complex = self.cast_into();
418                (this - other.cast_into()).into()
419            }
420            NT::Float(_) => {
421                let this: Float = self.cast_into();
422                (this - other.cast_into()).into()
423            }
424            NT::Int(_) => {
425                let this: Int = self.cast_into();
426                (this - other.cast_into()).into()
427            }
428            NT::UInt(_) => {
429                let this: UInt = self.cast_into();
430                (this - other.cast_into()).into()
431            }
432            NT::Number => panic!("A number instance must have a specific type, not Number"),
433        }
434    }
435}
436
437impl SubAssign for Number {
438    fn sub_assign(&mut self, other: Self) {
439        let difference = *self - other;
440        *self = difference;
441    }
442}
443
444impl Sum for Number {
445    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
446        let mut sum = NumberType::Number.zero();
447        for i in iter {
448            sum = sum + i;
449        }
450        sum
451    }
452}
453
454impl Mul for Number {
455    type Output = Self;
456
457    fn mul(self, other: Number) -> Self {
458        let dtype = Ord::max(self.class(), other.class());
459
460        use NumberType as NT;
461
462        match dtype {
463            NT::Bool => {
464                let this: Boolean = self.cast_into();
465                (this * other.cast_into()).into()
466            }
467            NT::Complex(_) => {
468                let this: Complex = self.cast_into();
469                (this * other.cast_into()).into()
470            }
471            NT::Float(_) => {
472                let this: Float = self.cast_into();
473                (this * other.cast_into()).into()
474            }
475            NT::Int(_) => {
476                let this: Int = self.cast_into();
477                (this * other.cast_into()).into()
478            }
479            NT::UInt(_) => {
480                let this: UInt = self.cast_into();
481                (this * other.cast_into()).into()
482            }
483            NT::Number => panic!("A number instance must have a specific type, not Number"),
484        }
485    }
486}
487
488impl MulAssign for Number {
489    fn mul_assign(&mut self, other: Self) {
490        let product = *self * other;
491        *self = product;
492    }
493}
494
495impl Div for Number {
496    type Output = Self;
497
498    fn div(self, other: Number) -> Self {
499        let dtype = Ord::max(self.class(), other.class());
500
501        use NumberType as NT;
502
503        match dtype {
504            NT::Number => panic!("A number instance must have a specific type, not Number"),
505            NT::Complex(_) => {
506                let this: Complex = self.cast_into();
507                (this / other.cast_into()).into()
508            }
509            NT::Float(_) => {
510                let this: Float = self.cast_into();
511                (this / other.cast_into()).into()
512            }
513            NT::Int(_) => {
514                let this: Int = self.cast_into();
515                (this / other.cast_into()).into()
516            }
517            NT::UInt(_) => {
518                let this: UInt = self.cast_into();
519                (this / other.cast_into()).into()
520            }
521            NT::Bool => {
522                let this: Boolean = self.cast_into();
523                (this / other.cast_into()).into()
524            }
525        }
526    }
527}
528
529impl DivAssign for Number {
530    fn div_assign(&mut self, other: Self) {
531        let div = *self / other;
532        *self = div;
533    }
534}
535
536impl Product for Number {
537    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
538        let zero = NumberType::Number.zero();
539        let mut product = NumberType::Number.one();
540
541        for i in iter {
542            if i == zero {
543                return zero;
544            }
545
546            product = product * i;
547        }
548        product
549    }
550}
551
552macro_rules! trig {
553    ($fun:ident) => {
554        fn $fun(self) -> Self::Out {
555            match self {
556                Self::Bool(b) => b.$fun().into(),
557                Self::Complex(c) => c.$fun().into(),
558                Self::Float(f) => f.$fun().into(),
559                Self::Int(i) => i.$fun().into(),
560                Self::UInt(u) => u.$fun().into(),
561            }
562        }
563    };
564}
565
566impl Trigonometry for Number {
567    type Out = Self;
568
569    trig! {asin}
570    trig! {sin}
571    trig! {asinh}
572    trig! {sinh}
573
574    trig! {acos}
575    trig! {cos}
576    trig! {acosh}
577    trig! {cosh}
578
579    trig! {atan}
580    trig! {tan}
581    trig! {atanh}
582    trig! {tanh}
583}
584
585impl Default for Number {
586    fn default() -> Self {
587        Self::Bool(Boolean::default())
588    }
589}
590
591impl From<bool> for Number {
592    fn from(b: bool) -> Self {
593        Self::Bool(b.into())
594    }
595}
596
597impl From<Boolean> for Number {
598    fn from(b: Boolean) -> Number {
599        Number::Bool(b)
600    }
601}
602
603impl From<u8> for Number {
604    fn from(u: u8) -> Self {
605        Self::UInt(u.into())
606    }
607}
608
609impl From<u16> for Number {
610    fn from(u: u16) -> Self {
611        Self::UInt(u.into())
612    }
613}
614
615impl From<u32> for Number {
616    fn from(u: u32) -> Self {
617        Self::UInt(u.into())
618    }
619}
620
621impl From<u64> for Number {
622    fn from(u: u64) -> Self {
623        Self::UInt(u.into())
624    }
625}
626
627impl From<UInt> for Number {
628    fn from(u: UInt) -> Number {
629        Number::UInt(u)
630    }
631}
632
633impl From<i8> for Number {
634    fn from(i: i8) -> Self {
635        Self::Int(i.into())
636    }
637}
638
639impl From<i16> for Number {
640    fn from(i: i16) -> Self {
641        Self::Int(i.into())
642    }
643}
644
645impl From<i32> for Number {
646    fn from(i: i32) -> Self {
647        Self::Int(i.into())
648    }
649}
650
651impl From<i64> for Number {
652    fn from(i: i64) -> Self {
653        Self::Int(i.into())
654    }
655}
656
657impl From<Int> for Number {
658    fn from(i: Int) -> Number {
659        Number::Int(i)
660    }
661}
662
663impl From<f32> for Number {
664    fn from(f: f32) -> Self {
665        Self::Float(f.into())
666    }
667}
668
669impl From<f64> for Number {
670    fn from(f: f64) -> Self {
671        Self::Float(f.into())
672    }
673}
674
675impl From<Float> for Number {
676    fn from(f: Float) -> Number {
677        Number::Float(f)
678    }
679}
680
681impl From<[f32; 2]> for Number {
682    fn from(arr: [f32; 2]) -> Self {
683        Self::Complex(arr.into())
684    }
685}
686
687impl From<[f64; 2]> for Number {
688    fn from(arr: [f64; 2]) -> Self {
689        Self::Complex(arr.into())
690    }
691}
692
693impl From<_Complex<f32>> for Number {
694    fn from(c: _Complex<f32>) -> Self {
695        Self::Complex(c.into())
696    }
697}
698
699impl From<_Complex<f64>> for Number {
700    fn from(c: _Complex<f64>) -> Self {
701        Self::Complex(c.into())
702    }
703}
704
705impl From<Complex> for Number {
706    fn from(c: Complex) -> Number {
707        Number::Complex(c)
708    }
709}
710
711impl FromStr for Number {
712    type Err = Error;
713
714    fn from_str(s: &str) -> Result<Self, Self::Err> {
715        let s = s.trim();
716
717        if s.is_empty() {
718            Err(Error(
719                "cannot parse a Number from an empty string".to_string(),
720            ))
721        } else if s.len() == 1 {
722            Int::from_str(s).map(Self::from)
723        } else if s.contains("e+") || s.contains("e-") {
724            Float::from_str(s).map(Self::from)
725        } else if s[1..].contains('+') || s[1..].contains('-') {
726            Complex::from_str(s).map(Self::from)
727        } else if s.contains('.') || s.contains('e') {
728            Float::from_str(s).map(Self::from)
729        } else {
730            Int::from_str(s).map(Self::from)
731        }
732    }
733}
734
735impl CastFrom<Number> for Boolean {
736    fn cast_from(number: Number) -> Boolean {
737        if number == number.class().zero() {
738            false.into()
739        } else {
740            true.into()
741        }
742    }
743}
744
745impl CastFrom<Number> for bool {
746    fn cast_from(n: Number) -> bool {
747        Boolean::cast_from(n).cast_into()
748    }
749}
750
751impl CastFrom<Number> for _Complex<f32> {
752    fn cast_from(n: Number) -> _Complex<f32> {
753        Complex::cast_from(n).cast_into()
754    }
755}
756
757impl CastFrom<Number> for _Complex<f64> {
758    fn cast_from(n: Number) -> _Complex<f64> {
759        Complex::cast_from(n).cast_into()
760    }
761}
762
763impl CastFrom<Number> for f32 {
764    fn cast_from(n: Number) -> f32 {
765        Float::cast_from(n).cast_into()
766    }
767}
768impl CastFrom<Number> for f64 {
769    fn cast_from(n: Number) -> f64 {
770        Float::cast_from(n).cast_into()
771    }
772}
773
774impl CastFrom<Number> for Float {
775    fn cast_from(number: Number) -> Float {
776        use Number::*;
777        match number {
778            Bool(b) => Self::cast_from(b),
779            Complex(c) => Self::cast_from(c),
780            Float(f) => f,
781            Int(i) => Self::cast_from(i),
782            UInt(u) => Self::cast_from(u),
783        }
784    }
785}
786
787impl CastFrom<Number> for i8 {
788    fn cast_from(n: Number) -> i8 {
789        Int::cast_from(n).cast_into()
790    }
791}
792
793impl CastFrom<Number> for i16 {
794    fn cast_from(n: Number) -> i16 {
795        Int::cast_from(n).cast_into()
796    }
797}
798
799impl CastFrom<Number> for i32 {
800    fn cast_from(n: Number) -> i32 {
801        Int::cast_from(n).cast_into()
802    }
803}
804
805impl CastFrom<Number> for i64 {
806    fn cast_from(n: Number) -> i64 {
807        Int::cast_from(n).cast_into()
808    }
809}
810
811impl CastFrom<Number> for Int {
812    fn cast_from(number: Number) -> Int {
813        use Number::*;
814        match number {
815            Bool(b) => Self::cast_from(b),
816            Complex(c) => Self::cast_from(c),
817            Float(f) => Self::cast_from(f),
818            Int(i) => i,
819            UInt(u) => Self::cast_from(u),
820        }
821    }
822}
823
824impl CastFrom<Number> for u8 {
825    fn cast_from(n: Number) -> u8 {
826        UInt::cast_from(n).cast_into()
827    }
828}
829
830impl CastFrom<Number> for u16 {
831    fn cast_from(n: Number) -> u16 {
832        UInt::cast_from(n).cast_into()
833    }
834}
835
836impl CastFrom<Number> for u32 {
837    fn cast_from(n: Number) -> u32 {
838        UInt::cast_from(n).cast_into()
839    }
840}
841
842impl CastFrom<Number> for u64 {
843    fn cast_from(n: Number) -> u64 {
844        UInt::cast_from(n).cast_into()
845    }
846}
847
848impl CastFrom<Number> for usize {
849    fn cast_from(n: Number) -> usize {
850        UInt::cast_from(n).cast_into()
851    }
852}
853
854impl CastFrom<Number> for UInt {
855    fn cast_from(number: Number) -> UInt {
856        use Number::*;
857        match number {
858            Bool(b) => Self::cast_from(b),
859            Complex(c) => Self::cast_from(c),
860            Float(f) => Self::cast_from(f),
861            Int(i) => Self::cast_from(i),
862            UInt(u) => u,
863        }
864    }
865}
866
867/// Defines a collation order for [`Number`].
868#[derive(Copy, Clone, Default, Eq, PartialEq)]
869pub struct NumberCollator {
870    bool: Collator<Boolean>,
871    complex: ComplexCollator,
872    float: FloatCollator,
873    int: Collator<Int>,
874    uint: Collator<UInt>,
875}
876
877impl Collate for NumberCollator {
878    type Value = Number;
879
880    fn cmp(&self, left: &Self::Value, right: &Self::Value) -> Ordering {
881        match (left, right) {
882            (Number::Bool(l), Number::Bool(r)) => self.bool.cmp(l, r),
883            (Number::Complex(l), Number::Complex(r)) => self.complex.cmp(l, r),
884            (Number::Float(l), Number::Float(r)) => self.float.cmp(l, r),
885            (Number::Int(l), Number::Int(r)) => self.int.cmp(l, r),
886            (Number::UInt(l), Number::UInt(r)) => self.uint.cmp(l, r),
887            (l, r) => {
888                let dtype = Ord::max(l.class(), r.class());
889                let l = l.into_type(dtype);
890                let r = r.into_type(dtype);
891                self.cmp(&l, &r)
892            }
893        }
894    }
895}
896
897/// A struct for deserializing a `Number` which implements
898/// [`destream::de::Visitor`] and [`serde::de::Visitor`].
899#[cfg(any(feature = "serde", feature = "stream"))]
900pub struct NumberVisitor;
901
902#[cfg(any(feature = "serde", feature = "stream"))]
903impl NumberVisitor {
904    #[inline]
905    fn bool<E>(self, b: bool) -> Result<Number, E> {
906        Ok(Number::Bool(b.into()))
907    }
908
909    #[inline]
910    fn i8<E>(self, i: i8) -> Result<Number, E> {
911        Ok(Number::Int(Int::I16(i as i16)))
912    }
913
914    #[inline]
915    fn i16<E>(self, i: i16) -> Result<Number, E> {
916        Ok(Number::Int(Int::I16(i)))
917    }
918
919    #[inline]
920    fn i32<E>(self, i: i32) -> Result<Number, E> {
921        Ok(Number::Int(Int::I32(i)))
922    }
923
924    #[inline]
925    fn i64<E>(self, i: i64) -> Result<Number, E> {
926        Ok(Number::Int(Int::I64(i)))
927    }
928
929    #[inline]
930    fn u8<E>(self, u: u8) -> Result<Number, E> {
931        Ok(Number::UInt(UInt::U8(u)))
932    }
933
934    #[inline]
935    fn u16<E>(self, u: u16) -> Result<Number, E> {
936        Ok(Number::UInt(UInt::U16(u)))
937    }
938
939    #[inline]
940    fn u32<E>(self, u: u32) -> Result<Number, E> {
941        Ok(Number::UInt(UInt::U32(u)))
942    }
943
944    #[inline]
945    fn u64<E>(self, u: u64) -> Result<Number, E> {
946        Ok(Number::UInt(UInt::U64(u)))
947    }
948
949    #[inline]
950    fn f32<E>(self, f: f32) -> Result<Number, E> {
951        Ok(Number::Float(Float::F32(f)))
952    }
953
954    #[inline]
955    fn f64<E>(self, f: f64) -> Result<Number, E> {
956        Ok(Number::Float(Float::F64(f)))
957    }
958}
959
960impl fmt::Debug for Number {
961    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
962        write!(f, "{} ({})", self, self.class())
963    }
964}
965
966impl fmt::Display for Number {
967    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
968        match self {
969            Number::Bool(b) => fmt::Display::fmt(b, f),
970            Number::Complex(c) => fmt::Display::fmt(c, f),
971            Number::Float(n) => fmt::Display::fmt(n, f),
972            Number::Int(i) => fmt::Display::fmt(i, f),
973            Number::UInt(u) => fmt::Display::fmt(u, f),
974        }
975    }
976}
977
978#[cfg(test)]
979mod tests {
980    use super::*;
981
982    #[test]
983    fn test_complex() {
984        let n = Complex::from([1.23, -3.14]);
985        assert_eq!(n.re(), Float::from(1.23));
986        assert_eq!(n.im(), Float::from(-3.14));
987    }
988
989    #[test]
990    fn test_log() {
991        let n = 1.23f32;
992        assert_eq!(n.ln(), f32::cast_from(Number::from(n).ln()));
993        assert_eq!(
994            (-n).ln().is_nan(),
995            f32::cast_from(Number::from(-n).ln()).is_nan()
996        );
997    }
998
999    #[test]
1000    fn test_ops() {
1001        let ones = [
1002            Number::from(true),
1003            Number::from(1u8),
1004            Number::from(1u16),
1005            Number::from(1u32),
1006            Number::from(1u64),
1007            Number::from(1i16),
1008            Number::from(1i32),
1009            Number::from(1i64),
1010            Number::from(1f32),
1011            Number::from(1f64),
1012            Number::from(_Complex::new(1f32, 0f32)),
1013            Number::from(_Complex::new(1f64, 0f64)),
1014        ];
1015
1016        let f = Number::from(false);
1017        let t = Number::from(true);
1018        let two = Number::from(2);
1019
1020        for one in &ones {
1021            let one = *one;
1022            let zero = one.class().zero();
1023
1024            assert_eq!(one, one.class().one());
1025
1026            assert_eq!(two, one * two);
1027            assert_eq!(one, (one * two) - one);
1028            assert_eq!(two, (one * two) / one);
1029            assert_eq!(zero, one * zero);
1030            assert_eq!(two.log(Float::cast_from(two)), one);
1031            assert_eq!(two.ln() / two.ln(), one);
1032
1033            if one.is_real() {
1034                assert_eq!(Number::from(2 % 1), two % one);
1035                assert_eq!(one, one.pow(zero));
1036                assert_eq!(one * one, one.pow(two));
1037                assert_eq!(two.pow(two), (one * two).pow(two));
1038            }
1039
1040            assert_eq!(f, one.not());
1041            assert_eq!(f, one.and(zero));
1042            assert_eq!(t, one.or(zero));
1043            assert_eq!(t, one.xor(zero));
1044        }
1045    }
1046
1047    #[test]
1048    fn test_parse() {
1049        assert_eq!(Number::from_str("12").unwrap(), Number::from(12));
1050        assert_eq!(Number::from_str("1e6").unwrap(), Number::from(1e6));
1051        assert_eq!(Number::from_str("1e-6").unwrap(), Number::from(1e-6));
1052        assert_eq!(Number::from_str("1e-06").unwrap(), Number::from(1e-6));
1053        assert_eq!(Number::from_str("+31.4").unwrap(), Number::from(31.4));
1054        assert_eq!(Number::from_str("-3.14").unwrap(), Number::from(-3.14));
1055        assert_eq!(
1056            Number::from_str("3.14+1.414i").unwrap(),
1057            Number::from(num::Complex::new(3.14, 1.414))
1058        );
1059        assert_eq!(
1060            Number::from_str("1+2i").unwrap(),
1061            Number::from(num::Complex::new(1., 2.))
1062        );
1063        assert_eq!(
1064            Number::from_str("1.0-2i").unwrap(),
1065            Number::from(num::Complex::new(1., -2.))
1066        );
1067    }
1068}