number_general/
class.rs

1use std::cmp::Ordering;
2use std::fmt;
3use std::iter::{Product, Sum};
4use std::ops::*;
5
6use safecast::*;
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10use super::instance::{Boolean, Complex, Float, Int, UInt};
11use super::{Number, _Complex};
12
13/// Defines common properties of numeric types supported by [`Number`].
14pub trait NumberClass: Default + Into<NumberType> + Ord + Send + fmt::Display {
15    type Instance: NumberInstance;
16
17    /// Cast the given `Number` into an instance of this type.
18    fn cast(&self, n: Number) -> Self::Instance;
19
20    /// Return `true` if this is a complex type.
21    fn is_complex(&self) -> bool {
22        return false;
23    }
24
25    /// Return `false` if this is a complex type.
26    fn is_real(&self) -> bool {
27        !self.is_complex()
28    }
29
30    /// Return the maximum size of this type of [`Number`], in bits.
31    fn size(self) -> usize;
32
33    /// Return `1` as an instance of this type.
34    fn one(&self) -> <Self as NumberClass>::Instance;
35
36    /// Return `0` as an instance of this type.
37    fn zero(&self) -> <Self as NumberClass>::Instance;
38}
39
40/// Defines common operations on numeric types supported by [`Number`].
41pub trait NumberInstance:
42    Copy
43    + Default
44    + Sized
45    + From<Boolean>
46    + Into<Number>
47    + Add<Output = Self>
48    + AddAssign
49    + Sub<Output = Self>
50    + SubAssign
51    + Mul<Output = Self>
52    + MulAssign
53    + Div<Output = Self>
54    + DivAssign
55    + Product
56    + Sum
57    + fmt::Debug
58    + fmt::Display
59{
60    type Abs: NumberInstance;
61    type Exp: NumberInstance;
62    type Log: NumberInstance;
63    type Round: NumberInstance;
64    type Class: NumberClass<Instance = Self>;
65
66    /// Get an impl of [`NumberClass`] describing this number.
67    fn class(&self) -> Self::Class;
68
69    /// Cast this number into the specified [`NumberClass`].
70    fn into_type(
71        self,
72        dtype: <Self as NumberInstance>::Class,
73    ) -> <<Self as NumberInstance>::Class as NumberClass>::Instance;
74
75    /// Calculate the absolute value of this number.
76    fn abs(self) -> Self::Abs;
77
78    /// Raise `e` to the power of this number.
79    fn exp(self) -> Self::Exp;
80
81    /// Compute the natural logarithm of this number.
82    fn ln(self) -> Self::Log;
83
84    /// Compute the logarithm of this number with respect to the given `base`.
85    fn log<N: NumberInstance>(self, base: N) -> Self::Log
86    where
87        Float: From<N>;
88
89    /// Raise this number to the given exponent.
90    ///
91    /// Panics: if the given exponent is a complex number.
92    fn pow(self, exp: Number) -> Self;
93
94    /// Return `true` if `self` and `other` are nonzero.
95    fn and(self, other: Self) -> Self
96    where
97        Boolean: CastFrom<Self>,
98    {
99        Boolean::cast_from(self)
100            .and(Boolean::cast_from(other))
101            .into()
102    }
103
104    /// Return `true` if this number is zero.
105    fn not(self) -> Self
106    where
107        Boolean: CastFrom<Self>,
108    {
109        Boolean::cast_from(self).not().into()
110    }
111
112    /// Return `true` if `self` or `other` is nonzero.
113    fn or(self, other: Self) -> Self
114    where
115        Boolean: CastFrom<Self>,
116    {
117        let this = Boolean::cast_from(self);
118        let that = Boolean::cast_from(other);
119        this.or(that).into()
120    }
121
122    /// Return this number rounded to the nearest integer.
123    fn round(self) -> Self::Round;
124
125    /// Return `true` if exactly one of `self` and `other` is zero.
126    fn xor(self, other: Self) -> Self
127    where
128        Boolean: CastFrom<Self>,
129    {
130        let this = Boolean::cast_from(self);
131        let that = Boolean::cast_from(other);
132        this.xor(that).into()
133    }
134}
135
136/// Trigonometric functions.
137pub trait Trigonometry {
138    type Out: NumberInstance;
139
140    /// Arcsine
141    fn asin(self) -> Self::Out;
142
143    /// Sine
144    fn sin(self) -> Self::Out;
145
146    /// Hyperbolic arcsine
147    fn asinh(self) -> Self::Out;
148
149    /// Hyperbolic sine
150    fn sinh(self) -> Self::Out;
151
152    /// Hyperbolic arccosine
153    fn acos(self) -> Self::Out;
154
155    /// Cosine
156    fn cos(self) -> Self::Out;
157
158    /// Hyperbolic arccosine
159    fn acosh(self) -> Self::Out;
160
161    /// Hyperbolic cosine
162    fn cosh(self) -> Self::Out;
163
164    /// Arctangent
165    fn atan(self) -> Self::Out;
166
167    /// Tangent
168    fn tan(self) -> Self::Out;
169
170    /// Hyperbolic arctangent
171    fn atanh(self) -> Self::Out;
172
173    /// Hyperbolic tangent
174    fn tanh(self) -> Self::Out;
175}
176
177/// Defines common operations on real (i.e. not `Complex`) numbers.
178pub trait RealInstance: PartialEq + PartialOrd + Sized {
179    const ONE: Self;
180    const ZERO: Self;
181
182    /// Return `true` if this is zero or a positive number.
183    fn is_positive(&self) -> bool {
184        self >= &Self::ZERO
185    }
186
187    /// Return `true` if this is a negative number.
188    fn is_negative(&self) -> bool {
189        self < &Self::ZERO
190    }
191
192    /// Return `true` if this is zero.
193    fn is_zero(&self) -> bool {
194        self == &Self::ZERO
195    }
196}
197
198/// Defines common operations on floating-point numeric types.
199pub trait FloatInstance {
200    /// Return `true` if this `Number` is infinite (e.g. [`f32::INFINITY`]).
201    fn is_infinite(&self) -> bool;
202
203    /// Return `true` if this is not a valid number (NaN).
204    fn is_nan(&self) -> bool;
205}
206
207/// The type of a [`Complex`] number.
208#[derive(Clone, Copy, Hash, Eq, PartialEq)]
209#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
210pub enum ComplexType {
211    C32,
212    C64,
213    Complex,
214}
215
216impl Default for ComplexType {
217    fn default() -> Self {
218        Self::Complex
219    }
220}
221
222impl NumberClass for ComplexType {
223    type Instance = Complex;
224
225    fn cast(&self, n: Number) -> Complex {
226        match self {
227            Self::C64 => Complex::C64(n.cast_into()),
228            _ => Complex::C32(n.cast_into()),
229        }
230    }
231
232    fn is_complex(&self) -> bool {
233        true
234    }
235
236    fn size(self) -> usize {
237        match self {
238            Self::C32 => 8,
239            Self::C64 => 16,
240            Self::Complex => 16,
241        }
242    }
243
244    fn one(&self) -> Complex {
245        match self {
246            Self::C32 => _Complex::<f32>::new(1f32, 0f32).into(),
247            Self::C64 => _Complex::<f64>::new(1f64, 0f64).into(),
248            Self::Complex => _Complex::<f32>::new(1f32, 0f32).into(),
249        }
250    }
251
252    fn zero(&self) -> Complex {
253        match self {
254            Self::C32 => _Complex::<f32>::new(0f32, 0f32).into(),
255            Self::C64 => _Complex::<f64>::new(0f64, 0f64).into(),
256            Self::Complex => _Complex::<f32>::new(0f32, 0f32).into(),
257        }
258    }
259}
260
261impl Ord for ComplexType {
262    fn cmp(&self, other: &Self) -> Ordering {
263        match (self, other) {
264            (Self::C32, Self::C32) => Ordering::Equal,
265            (Self::C64, Self::C64) => Ordering::Equal,
266            (Self::Complex, Self::Complex) => Ordering::Equal,
267
268            (Self::Complex, _) => Ordering::Greater,
269            (_, Self::Complex) => Ordering::Less,
270
271            (Self::C64, Self::C32) => Ordering::Greater,
272            (Self::C32, Self::C64) => Ordering::Less,
273        }
274    }
275}
276
277impl PartialOrd for ComplexType {
278    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
279        Some(self.cmp(other))
280    }
281}
282
283impl From<ComplexType> for NumberType {
284    fn from(ct: ComplexType) -> NumberType {
285        Self::Complex(ct)
286    }
287}
288
289impl fmt::Debug for ComplexType {
290    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
291        fmt::Display::fmt(self, f)
292    }
293}
294
295impl fmt::Display for ComplexType {
296    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
297        match self {
298            Self::C32 => write!(f, "32-bit complex number"),
299            Self::C64 => write!(f, "64-bit complex number"),
300            Self::Complex => write!(f, "complex number"),
301        }
302    }
303}
304
305/// The type of a [`Boolean`].
306#[derive(Clone, Copy, Default, Hash, Eq, PartialEq)]
307#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
308pub struct BooleanType;
309
310impl NumberClass for BooleanType {
311    type Instance = Boolean;
312
313    fn cast(&self, n: Number) -> Boolean {
314        n.cast_into()
315    }
316
317    fn size(self) -> usize {
318        1
319    }
320
321    fn one(&self) -> Boolean {
322        true.into()
323    }
324
325    fn zero(&self) -> Boolean {
326        false.into()
327    }
328}
329
330impl Ord for BooleanType {
331    fn cmp(&self, _other: &Self) -> Ordering {
332        Ordering::Equal
333    }
334}
335
336impl PartialOrd for BooleanType {
337    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
338        Some(self.cmp(other))
339    }
340}
341
342impl From<BooleanType> for NumberType {
343    fn from(_bt: BooleanType) -> NumberType {
344        NumberType::Bool
345    }
346}
347
348impl fmt::Debug for BooleanType {
349    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
350        fmt::Display::fmt(self, f)
351    }
352}
353
354impl fmt::Display for BooleanType {
355    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
356        write!(f, "Boolean")
357    }
358}
359
360/// The type of a [`Float`].
361#[derive(Clone, Copy, Hash, Eq, PartialEq)]
362#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
363pub enum FloatType {
364    F32,
365    F64,
366    Float,
367}
368
369impl Default for FloatType {
370    fn default() -> Self {
371        Self::Float
372    }
373}
374
375impl NumberClass for FloatType {
376    type Instance = Float;
377
378    fn cast(&self, n: Number) -> Float {
379        match self {
380            Self::F64 => Float::F64(n.cast_into()),
381            _ => Float::F32(n.cast_into()),
382        }
383    }
384
385    fn size(self) -> usize {
386        match self {
387            Self::F32 => 4,
388            Self::F64 => 8,
389            Self::Float => 8,
390        }
391    }
392
393    fn one(&self) -> Float {
394        match self {
395            Self::F32 => 1f32.into(),
396            Self::F64 => 1f64.into(),
397            Self::Float => 1f32.into(),
398        }
399    }
400
401    fn zero(&self) -> Float {
402        match self {
403            Self::F32 => 0f32.into(),
404            Self::F64 => 0f64.into(),
405            Self::Float => 0f32.into(),
406        }
407    }
408}
409
410impl Ord for FloatType {
411    fn cmp(&self, other: &Self) -> Ordering {
412        match (self, other) {
413            (Self::F32, Self::F32) => Ordering::Equal,
414            (Self::F64, Self::F64) => Ordering::Equal,
415            (Self::Float, Self::Float) => Ordering::Equal,
416
417            (Self::Float, _) => Ordering::Greater,
418            (_, Self::Float) => Ordering::Less,
419
420            (Self::F64, Self::F32) => Ordering::Greater,
421            (Self::F32, Self::F64) => Ordering::Less,
422        }
423    }
424}
425
426impl PartialOrd for FloatType {
427    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
428        Some(self.cmp(other))
429    }
430}
431
432impl From<FloatType> for NumberType {
433    fn from(ft: FloatType) -> NumberType {
434        NumberType::Float(ft)
435    }
436}
437
438impl fmt::Debug for FloatType {
439    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440        fmt::Display::fmt(self, f)
441    }
442}
443
444impl fmt::Display for FloatType {
445    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
446        use FloatType::*;
447        match self {
448            F32 => write!(f, "32-bit float"),
449            F64 => write!(f, "64-bit float"),
450            Float => write!(f, "float"),
451        }
452    }
453}
454
455/// The type of an [`Int`].
456#[derive(Clone, Copy, Hash, Eq, PartialEq)]
457#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
458pub enum IntType {
459    I8,
460    I16,
461    I32,
462    I64,
463    Int,
464}
465
466impl Default for IntType {
467    fn default() -> Self {
468        Self::Int
469    }
470}
471
472impl NumberClass for IntType {
473    type Instance = Int;
474
475    fn cast(&self, n: Number) -> Int {
476        match self {
477            Self::I8 => Int::I8(n.cast_into()),
478            Self::I16 => Int::I16(n.cast_into()),
479            Self::Int | Self::I32 => Int::I32(n.cast_into()),
480            Self::I64 => Int::I64(n.cast_into()),
481        }
482    }
483
484    fn size(self) -> usize {
485        match self {
486            Self::I8 => 1,
487            Self::I16 => 2,
488            Self::I32 => 4,
489            Self::I64 => 8,
490            Self::Int => 8,
491        }
492    }
493
494    fn one(&self) -> Int {
495        match self {
496            Self::I8 => 1i8.into(),
497            Self::I16 => 1i16.into(),
498            Self::I32 => 1i32.into(),
499            Self::I64 => 1i64.into(),
500            Self::Int => 1i16.into(),
501        }
502    }
503
504    fn zero(&self) -> Int {
505        match self {
506            Self::I8 => 0i8.into(),
507            Self::I16 => 0i16.into(),
508            Self::I32 => 0i32.into(),
509            Self::I64 => 0i64.into(),
510            Self::Int => 0i16.into(),
511        }
512    }
513}
514
515impl Ord for IntType {
516    fn cmp(&self, other: &Self) -> Ordering {
517        match (self, other) {
518            (this, that) if this == that => Ordering::Equal,
519
520            (Self::Int, _) => Ordering::Greater,
521            (_, Self::Int) => Ordering::Less,
522
523            (Self::I64, _) => Ordering::Greater,
524            (_, Self::I64) => Ordering::Less,
525
526            (Self::I32, _) => Ordering::Greater,
527            (_, Self::I32) => Ordering::Less,
528
529            (Self::I16, _) => Ordering::Greater,
530            (_, Self::I16) => Ordering::Less,
531
532            (Self::I8, _) => Ordering::Less,
533        }
534    }
535}
536
537impl PartialOrd for IntType {
538    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
539        Some(self.cmp(other))
540    }
541}
542
543impl From<IntType> for NumberType {
544    fn from(it: IntType) -> NumberType {
545        NumberType::Int(it)
546    }
547}
548
549impl fmt::Debug for IntType {
550    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
551        fmt::Display::fmt(self, f)
552    }
553}
554
555impl fmt::Display for IntType {
556    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
557        match self {
558            Self::I8 => write!(f, "8-bit integer"),
559            Self::I16 => write!(f, "16-bit integer"),
560            Self::I32 => write!(f, "32-bit integer"),
561            Self::I64 => write!(f, "64-bit integer"),
562            Self::Int => write!(f, "integer"),
563        }
564    }
565}
566
567/// The type of a [`UInt`].
568#[derive(Clone, Copy, Hash, Eq, PartialEq)]
569#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
570pub enum UIntType {
571    U8,
572    U16,
573    U32,
574    U64,
575    UInt,
576}
577
578impl Default for UIntType {
579    fn default() -> Self {
580        Self::UInt
581    }
582}
583
584impl NumberClass for UIntType {
585    type Instance = UInt;
586
587    fn cast(&self, n: Number) -> UInt {
588        match self {
589            Self::U8 => UInt::U8(n.cast_into()),
590            Self::U16 => UInt::U16(n.cast_into()),
591            Self::UInt | Self::U32 => UInt::U32(n.cast_into()),
592            Self::U64 => UInt::U64(n.cast_into()),
593        }
594    }
595
596    fn size(self) -> usize {
597        match self {
598            UIntType::U8 => 1,
599            UIntType::U16 => 2,
600            UIntType::U32 => 4,
601            UIntType::U64 => 8,
602            UIntType::UInt => 8,
603        }
604    }
605
606    fn one(&self) -> UInt {
607        match self {
608            Self::U8 => 1u8.into(),
609            Self::U16 => 1u16.into(),
610            Self::U32 => 1u32.into(),
611            Self::U64 => 1u64.into(),
612            Self::UInt => 1u8.into(),
613        }
614    }
615
616    fn zero(&self) -> UInt {
617        match self {
618            Self::U8 => 0u8.into(),
619            Self::U16 => 0u16.into(),
620            Self::U32 => 0u32.into(),
621            Self::U64 => 0u64.into(),
622            Self::UInt => 0u8.into(),
623        }
624    }
625}
626
627impl Ord for UIntType {
628    fn cmp(&self, other: &Self) -> Ordering {
629        match (self, other) {
630            (Self::U8, Self::U8) => Ordering::Equal,
631            (Self::U16, Self::U16) => Ordering::Equal,
632            (Self::U32, Self::U32) => Ordering::Equal,
633            (Self::U64, Self::U64) => Ordering::Equal,
634            (Self::UInt, Self::UInt) => Ordering::Equal,
635
636            (Self::UInt, _) => Ordering::Greater,
637            (_, Self::UInt) => Ordering::Less,
638
639            (Self::U64, _) => Ordering::Greater,
640            (_, Self::U64) => Ordering::Less,
641
642            (Self::U8, _) => Ordering::Less,
643            (_, Self::U8) => Ordering::Greater,
644
645            (Self::U32, Self::U16) => Ordering::Greater,
646            (Self::U16, Self::U32) => Ordering::Less,
647        }
648    }
649}
650
651impl PartialOrd for UIntType {
652    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
653        Some(self.cmp(other))
654    }
655}
656
657impl From<UIntType> for NumberType {
658    fn from(ut: UIntType) -> NumberType {
659        NumberType::UInt(ut)
660    }
661}
662
663impl fmt::Debug for UIntType {
664    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
665        fmt::Display::fmt(self, f)
666    }
667}
668
669impl fmt::Display for UIntType {
670    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
671        use UIntType::*;
672        match self {
673            U8 => write!(f, "8-bit unsigned"),
674            U16 => write!(f, "16-bit unsigned"),
675            U32 => write!(f, "32-bit unsigned"),
676            U64 => write!(f, "64-bit unsigned"),
677            UInt => write!(f, "uint"),
678        }
679    }
680}
681
682/// The type of a generic [`Number`].
683#[derive(Clone, Copy, Hash, Eq, PartialEq)]
684#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
685pub enum NumberType {
686    Bool,
687    Complex(ComplexType),
688    Float(FloatType),
689    Int(IntType),
690    UInt(UIntType),
691    Number,
692}
693
694impl NumberType {
695    pub fn uint64() -> Self {
696        NumberType::UInt(UIntType::U64)
697    }
698}
699
700impl Default for NumberType {
701    fn default() -> Self {
702        Self::Number
703    }
704}
705
706impl NumberClass for NumberType {
707    type Instance = Number;
708
709    fn is_complex(&self) -> bool {
710        match self {
711            Self::Bool => BooleanType.is_complex(),
712            Self::Complex(ct) => ct.is_complex(),
713            Self::Float(ft) => ft.is_complex(),
714            Self::Int(it) => it.is_complex(),
715            Self::UInt(ut) => ut.is_complex(),
716            Self::Number => false,
717        }
718    }
719
720    fn cast(&self, n: Number) -> Number {
721        match self {
722            Self::Bool => Number::Bool(n.cast_into()),
723            Self::Complex(ct) => Number::Complex(ct.cast(n)),
724            Self::Float(ft) => Number::Float(ft.cast(n)),
725            Self::Int(it) => Number::Int(it.cast(n)),
726            Self::UInt(ut) => Number::UInt(ut.cast(n)),
727            Self::Number => n,
728        }
729    }
730
731    fn size(self) -> usize {
732        use NumberType::*;
733        match self {
734            Bool => 1,
735            Complex(ct) => NumberClass::size(ct),
736            Float(ft) => NumberClass::size(ft),
737            Int(it) => NumberClass::size(it),
738            UInt(ut) => NumberClass::size(ut),
739
740            // a generic Number still has a distinct maximum size
741            Number => NumberClass::size(ComplexType::C64),
742        }
743    }
744
745    fn one(&self) -> Number {
746        use NumberType::*;
747        match self {
748            Bool | Number => true.into(),
749            Complex(ct) => ct.one().into(),
750            Float(ft) => ft.one().into(),
751            Int(it) => it.one().into(),
752            UInt(ut) => ut.one().into(),
753        }
754    }
755
756    fn zero(&self) -> Number {
757        use NumberType::*;
758        match self {
759            Bool | Number => false.into(),
760            Complex(ct) => ct.zero().into(),
761            Float(ft) => ft.zero().into(),
762            Int(it) => it.zero().into(),
763            UInt(ut) => ut.zero().into(),
764        }
765    }
766}
767
768impl Ord for NumberType {
769    fn cmp(&self, other: &Self) -> Ordering {
770        match (self, other) {
771            (Self::Bool, Self::Bool) => Ordering::Equal,
772            (Self::Complex(l), Self::Complex(r)) => l.cmp(r),
773            (Self::Float(l), Self::Float(r)) => l.cmp(r),
774            (Self::Int(l), Self::Int(r)) => l.cmp(r),
775            (Self::UInt(l), Self::UInt(r)) => l.cmp(r),
776
777            (Self::Number, Self::Number) => Ordering::Equal,
778            (Self::Number, _) => Ordering::Greater,
779            (_, Self::Number) => Ordering::Less,
780
781            (Self::Bool, _) => Ordering::Less,
782            (_, Self::Bool) => Ordering::Greater,
783
784            (Self::Complex(_), _) => Ordering::Greater,
785            (_, Self::Complex(_)) => Ordering::Less,
786
787            (Self::UInt(_), Self::Int(_)) => Ordering::Less,
788            (Self::UInt(_), Self::Float(_)) => Ordering::Less,
789            (Self::Int(_), Self::UInt(_)) => Ordering::Greater,
790            (Self::Float(_), Self::UInt(_)) => Ordering::Greater,
791            (Self::Int(_), Self::Float(_)) => Ordering::Less,
792            (Self::Float(_), Self::Int(_)) => Ordering::Greater,
793        }
794    }
795}
796
797impl PartialOrd for NumberType {
798    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
799        Some(self.cmp(other))
800    }
801}
802
803impl fmt::Debug for NumberType {
804    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
805        fmt::Display::fmt(self, f)
806    }
807}
808
809impl fmt::Display for NumberType {
810    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
811        use NumberType::*;
812        match self {
813            Bool => fmt::Debug::fmt(&BooleanType, f),
814            Complex(ct) => fmt::Debug::fmt(ct, f),
815            Float(ft) => fmt::Debug::fmt(ft, f),
816            Int(it) => fmt::Debug::fmt(it, f),
817            UInt(ut) => fmt::Debug::fmt(ut, f),
818            Number => write!(f, "Number"),
819        }
820    }
821}