reifydb_type/value/number/
promote.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the MIT, see license.md file
3
4#![cfg_attr(rustfmt, rustfmt_skip)]
5
6use crate::value::is::IsNumber;
7
8pub trait Promote<R> where Self: IsNumber, R: IsNumber {
9    type Output: IsNumber;
10    fn checked_promote(&self, r: &R) -> Option<(Self::Output, Self::Output)>;
11    fn saturating_promote(&self, r: &R) -> (Self::Output, Self::Output);
12    fn wrapping_promote(&self, r: &R) -> (Self::Output, Self::Output);
13
14}
15
16macro_rules! impl_promote_float_float {
17    ($l:ty, $r:ty => $common:ty) => {
18        impl Promote<$r> for $l {
19            type Output = $common;
20
21            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)> {
22                if self.is_finite() && r.is_finite() {
23                    Some((*self as $common, *r as $common))
24                } else {
25                    None
26                }
27            }
28
29            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
30                let l = if self.is_finite() {
31                    *self as $common
32                } else if self.is_sign_negative() {
33                    <$common>::MIN
34                } else {
35                    <$common>::MAX
36                };
37                let r = if r.is_finite() {
38                    *r as $common
39                } else if r.is_sign_negative() {
40                    <$common>::MIN
41                } else {
42                    <$common>::MAX
43                };
44                (l, r)
45            }
46
47            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
48                (*self as $common, *r as $common)
49            }
50        }
51    };
52}
53
54macro_rules! impl_promote_float_integer {
55    ($l:ty, $r:ty => $common:ty) => {
56        impl Promote<$r> for $l {
57            type Output = $common;
58
59            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)> {
60                if self.is_finite() {
61                    Some((*self as $common, *r as $common))
62                } else {
63                    None
64                }
65            }
66
67            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
68                let l = if self.is_finite() {
69                    *self as $common
70                } else if self.is_sign_negative() {
71                    <$common>::MIN
72                } else {
73                    <$common>::MAX
74                };
75
76                let r = *r as $common;
77                (l, r)
78            }
79
80            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
81                (*self as $common, *r as $common)
82            }
83        }
84    };
85}
86
87
88macro_rules! impl_promote_integer_float {
89    ($l:ty, $r:ty => $common:ty) => {
90        impl Promote<$r> for $l {
91            type Output = $common;
92
93            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)> {
94                if r.is_finite() {
95                    Some((*self as $common, *r as $common))
96                } else {
97                    None
98                }
99            }
100
101            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
102                let l = *self as $common;
103                let r = if r.is_finite() {
104                    *r as $common
105                } else if r.is_sign_negative() {
106                    <$common>::MIN
107                } else {
108                    <$common>::MAX
109                };
110                (l, r)
111            }
112
113            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
114                (*self as $common, *r as $common)
115            }
116        }
117    };
118}
119
120
121
122impl_promote_float_float!(f32, f32 => f64);
123impl_promote_float_float!(f32, f64 => f64); impl_promote_float_float!(f64, f32 => f64);
124impl_promote_float_float!(f64, f64 => f64);
125
126// float - signed
127
128impl_promote_float_integer!(f32, i8 => f64); impl_promote_integer_float!(i8, f32 => f64);
129impl_promote_float_integer!(f32, i16 => f64); impl_promote_integer_float!(i16, f32 => f64);
130impl_promote_float_integer!(f32, i32 => f64); impl_promote_integer_float!(i32, f32 => f64);
131impl_promote_float_integer!(f32, i64 => f64); impl_promote_integer_float!(i64, f32 => f64);
132impl_promote_float_integer!(f32, i128 => f64); impl_promote_integer_float!(i128, f32 => f64);
133
134impl_promote_float_integer!(f64, i8 => f64); impl_promote_integer_float!(i8, f64 => f64);
135impl_promote_float_integer!(f64, i16 => f64); impl_promote_integer_float!(i16, f64 => f64);
136impl_promote_float_integer!(f64, i32 => f64); impl_promote_integer_float!(i32, f64 => f64);
137impl_promote_float_integer!(f64, i64 => f64); impl_promote_integer_float!(i64, f64 => f64);
138impl_promote_float_integer!(f64, i128 => f64); impl_promote_integer_float!(i128, f64 => f64);
139
140// float - unsigned
141
142impl_promote_float_integer!(f32, u8 => f64); impl_promote_integer_float!(u8, f32 => f64);
143impl_promote_float_integer!(f32, u16 => f64); impl_promote_integer_float!(u16, f32 => f64);
144impl_promote_float_integer!(f32, u32 => f64); impl_promote_integer_float!(u32, f32 => f64);
145impl_promote_float_integer!(f32, u64 => f64); impl_promote_integer_float!(u64, f32 => f64);
146impl_promote_float_integer!(f32, u128 => f64); impl_promote_integer_float!(u128, f32 => f64);
147
148impl_promote_float_integer!(f64, u8 => f64); impl_promote_integer_float!(u8, f64 => f64);
149impl_promote_float_integer!(f64, u16 => f64); impl_promote_integer_float!(u16, f64 => f64);
150impl_promote_float_integer!(f64, u32 => f64); impl_promote_integer_float!(u32, f64 => f64);
151impl_promote_float_integer!(f64, u64 => f64); impl_promote_integer_float!(u64, f64 => f64);
152impl_promote_float_integer!(f64, u128 => f64); impl_promote_integer_float!(u128, f64 => f64);
153
154// signed - signed 
155macro_rules! impl_promote_signed_signed {
156    ($l:ty, $r:ty => $common:ty) => {
157        impl Promote<$r> for $l {
158            type Output = $common;
159
160            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)>{
161                let l: Option<$common> = <$common>::try_from(*self).ok();
162                let r: Option<$common> = <$common>::try_from(*r).ok();
163                match(l,r){
164                    (Some(l),Some(r)) => Some((l,r)),
165                    _ => None
166                }
167            }
168
169            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
170                let l = match <$common>::try_from(*self) {
171                    Ok(v) => v,
172                    Err(_) => if *self < 0 { <$common>::MIN } else { <$common>::MAX }};
173                let r = match <$common>::try_from(*r) {
174                    Ok(v) => v,
175                    Err(_) => if *r < 0 { <$common>::MIN } else { <$common>::MAX }};
176                (l, r)
177            }
178
179            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
180                (*self as $common, *r as $common)
181            }
182        }
183    };
184}
185impl_promote_signed_signed!(i8, i8 => i128);
186impl_promote_signed_signed!(i8, i16 => i128); impl_promote_signed_signed!(i16, i8 => i128);
187impl_promote_signed_signed!(i8, i32 => i128); impl_promote_signed_signed!(i32, i8 => i128);
188impl_promote_signed_signed!(i8, i64 => i128); impl_promote_signed_signed!(i64, i8 => i128);
189impl_promote_signed_signed!(i8, i128 => i128); impl_promote_signed_signed!(i128, i8 => i128);
190
191impl_promote_signed_signed!(i16, i16 => i128);
192impl_promote_signed_signed!(i16, i32 => i128); impl_promote_signed_signed!(i32, i16 => i128);
193impl_promote_signed_signed!(i16, i64 => i128); impl_promote_signed_signed!(i64, i16 => i128);
194impl_promote_signed_signed!(i16, i128 => i128); impl_promote_signed_signed!(i128, i16 => i128);
195
196impl_promote_signed_signed!(i32, i32 => i128);
197impl_promote_signed_signed!(i32, i64 => i128); impl_promote_signed_signed!(i64, i32 => i128);
198impl_promote_signed_signed!(i32, i128 => i128); impl_promote_signed_signed!(i128, i32 => i128);
199
200impl_promote_signed_signed!(i64, i64 => i128);
201impl_promote_signed_signed!(i64, i128 => i128); impl_promote_signed_signed!(i128, i64 => i128);
202
203impl_promote_signed_signed!(i128, i128 => i128);
204
205macro_rules! impl_promote_unsigned_unsigned {
206    ($l:ty, $r:ty => $common:ty) => {
207        impl Promote<$r> for $l {
208            type Output = $common;
209
210            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)>{
211                let l: Option<$common> = <$common>::try_from(*self).ok();
212                let r: Option<$common> = <$common>::try_from(*r).ok();
213                match(l,r){
214                    (Some(l),Some(r)) => Some((l,r)),
215                    _ => None
216                }
217            }
218
219            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
220                let l = match <$common>::try_from(*self) {
221                    Ok(v) => v,
222                    Err(_) =>  <$common>::MAX};
223                let r = match <$common>::try_from(*r) {
224                    Ok(v) => v,
225                    Err(_) => <$common>::MAX};
226                (l, r)
227            }
228
229            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
230                (*self as $common, *r as $common)
231            }
232        }
233    };
234}
235
236impl_promote_unsigned_unsigned!(u8, u8 => u128);
237impl_promote_unsigned_unsigned!(u8, u16 => u128); impl_promote_unsigned_unsigned!(u16, u8 => u128);
238impl_promote_unsigned_unsigned!(u8, u32 => u128); impl_promote_unsigned_unsigned!(u32, u8 => u128);
239impl_promote_unsigned_unsigned!(u8, u64 => u128); impl_promote_unsigned_unsigned!(u64, u8 => u128);
240impl_promote_unsigned_unsigned!(u8, u128 => u128); impl_promote_unsigned_unsigned!(u128, u8 => u128);
241
242impl_promote_unsigned_unsigned!(u16, u16 => u128);
243impl_promote_unsigned_unsigned!(u16, u32 => u128); impl_promote_unsigned_unsigned!(u32, u16 => u128);
244impl_promote_unsigned_unsigned!(u16, u64 => u128); impl_promote_unsigned_unsigned!(u64, u16 => u128);
245impl_promote_unsigned_unsigned!(u16, u128 => u128); impl_promote_unsigned_unsigned!(u128, u16 => u128);
246
247impl_promote_unsigned_unsigned!(u32, u32 => u128);
248impl_promote_unsigned_unsigned!(u32, u64 => u128); impl_promote_unsigned_unsigned!(u64, u32 => u128);
249impl_promote_unsigned_unsigned!(u32, u128 => u128); impl_promote_unsigned_unsigned!(u128, u32 => u128);
250
251impl_promote_unsigned_unsigned!(u64, u64 => u128);
252impl_promote_unsigned_unsigned!(u64, u128 => u128); impl_promote_unsigned_unsigned!(u128, u64 => u128);
253
254impl_promote_unsigned_unsigned!(u128, u128 => u128);
255
256
257macro_rules! impl_promote_signed_unsigned {
258    ($l:ty, $r:ty => $common:ty) => {
259        impl Promote<$r> for $l {
260            type Output = $common;
261
262            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)>{
263                let l: Option<$common> = <$common>::try_from(*self).ok();
264                let r: Option<$common> = <$common>::try_from(*r).ok();
265                match(l,r){
266                    (Some(l),Some(r)) => Some((l,r)),
267                    _ => None
268                }
269            }
270
271            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
272                let l = match <$common>::try_from(*self) {
273                    Ok(v) => v,
274                    Err(_) => if *self < 0 { <$common>::MIN } else { <$common>::MAX }};
275                let r = match <$common>::try_from(*r) {
276                    Ok(v) => v,
277                    Err(_) => <$common>::MAX};
278                (l, r)
279            }
280
281            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
282                (*self as $common, *r as $common)
283            }
284        }
285    };
286}
287
288macro_rules! impl_promote_unsigned_signed {
289    ($l:ty, $r:ty => $common:ty) => {
290        impl Promote<$r> for $l {
291            type Output = $common;
292
293            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)>{
294                let l: Option<$common> = <$common>::try_from(*self).ok();
295                let r: Option<$common> = <$common>::try_from(*r).ok();
296                match(l,r){
297                    (Some(l),Some(r)) => Some((l,r)),
298                    _ => None
299                }
300            }
301
302            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
303                let l = match <$common>::try_from(*self) {
304                    Ok(v) => v,
305                    Err(_) => <$common>::MAX};
306                let r = match <$common>::try_from(*r) {
307                    Ok(v) => v,
308                    Err(_) => if *r < 0 { <$common>::MIN } else { <$common>::MAX }};
309                (l, r)
310            }
311
312            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
313                (*self as $common, *r as $common)
314            }
315        }
316    };
317}
318
319impl_promote_signed_unsigned!(i8, u8 => i128);    impl_promote_unsigned_signed!(u8, i8 => i128);
320impl_promote_signed_unsigned!(i8, u16 => i128);   impl_promote_unsigned_signed!(u16, i8 => i128);
321impl_promote_signed_unsigned!(i8, u32 => i128);   impl_promote_unsigned_signed!(u32, i8 => i128);
322impl_promote_signed_unsigned!(i8, u64 => i128);   impl_promote_unsigned_signed!(u64, i8 => i128);
323impl_promote_signed_unsigned!(i8, u128 => i128);  impl_promote_unsigned_signed!(u128, i8 => i128);
324impl_promote_signed_unsigned!(i16, u8 => i128);   impl_promote_unsigned_signed!(u8, i16 => i128);
325impl_promote_signed_unsigned!(i16, u16 => i128);  impl_promote_unsigned_signed!(u16, i16 => i128);
326impl_promote_signed_unsigned!(i16, u32 => i128);  impl_promote_unsigned_signed!(u32, i16 => i128);
327impl_promote_signed_unsigned!(i16, u64 => i128);  impl_promote_unsigned_signed!(u64, i16 => i128);
328impl_promote_signed_unsigned!(i16, u128 => i128); impl_promote_unsigned_signed!(u128, i16 => i128);
329impl_promote_signed_unsigned!(i32, u8 => i128);   impl_promote_unsigned_signed!(u8, i32 => i128);
330impl_promote_signed_unsigned!(i32, u16 => i128);  impl_promote_unsigned_signed!(u16, i32 => i128);
331impl_promote_signed_unsigned!(i32, u32 => i128);  impl_promote_unsigned_signed!(u32, i32 => i128);
332impl_promote_signed_unsigned!(i32, u64 => i128);  impl_promote_unsigned_signed!(u64, i32 => i128);
333impl_promote_signed_unsigned!(i32, u128 => i128); impl_promote_unsigned_signed!(u128, i32 => i128);
334impl_promote_signed_unsigned!(i64, u8 => i128);   impl_promote_unsigned_signed!(u8, i64 => i128);
335impl_promote_signed_unsigned!(i64, u16 => i128);  impl_promote_unsigned_signed!(u16, i64 => i128);
336impl_promote_signed_unsigned!(i64, u32 => i128);  impl_promote_unsigned_signed!(u32, i64 => i128);
337impl_promote_signed_unsigned!(i64, u64 => i128);  impl_promote_unsigned_signed!(u64, i64 => i128);
338impl_promote_signed_unsigned!(i64, u128 => i128); impl_promote_unsigned_signed!(u128, i64 => i128);
339impl_promote_signed_unsigned!(i128, u8 => i128);   impl_promote_unsigned_signed!(u8, i128 => i128);
340impl_promote_signed_unsigned!(i128, u16 => i128);  impl_promote_unsigned_signed!(u16, i128 => i128);
341impl_promote_signed_unsigned!(i128, u32 => i128);  impl_promote_unsigned_signed!(u32, i128 => i128);
342impl_promote_signed_unsigned!(i128, u64 => i128);  impl_promote_unsigned_signed!(u64, i128 => i128);
343impl_promote_signed_unsigned!(i128, u128 => i128); impl_promote_unsigned_signed!(u128, i128 => i128);
344
345use crate::Decimal;
346use crate::value::{int::Int, uint::Uint};
347
348impl Promote<Int> for Int {
349    type Output = Int;
350
351    fn checked_promote(&self, r: &Int) -> Option<(Self::Output, Self::Output)> {
352        Some((self.clone(), r.clone()))
353    }
354
355    fn saturating_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
356        (self.clone(), r.clone())
357    }
358
359    fn wrapping_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
360        (self.clone(), r.clone())
361    }
362}
363
364impl Promote<Uint> for Uint {
365    type Output = Uint;
366
367    fn checked_promote(&self, r: &Uint) -> Option<(Self::Output, Self::Output)> {
368        Some((self.clone(), r.clone()))
369    }
370
371    fn saturating_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
372        (self.clone(), r.clone())
373    }
374
375    fn wrapping_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
376        (self.clone(), r.clone())
377    }
378}
379
380impl Promote<Decimal> for Decimal {
381    type Output = Decimal;
382
383    fn checked_promote(&self, r: &Decimal) -> Option<(Self::Output, Self::Output)> {
384        Some((self.clone(), r.clone()))
385    }
386
387    fn saturating_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
388        (self.clone(), r.clone())
389    }
390
391    fn wrapping_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
392        (self.clone(), r.clone())
393    }
394}
395
396impl Promote<Uint> for Int {
397    type Output = Int;
398
399    fn checked_promote(&self, r: &Uint) -> Option<(Self::Output, Self::Output)> {
400        let r_as_int = Int::from(r.0.clone());
401        Some((self.clone(), r_as_int))
402    }
403
404    fn saturating_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
405        let r_as_int = Int::from(r.0.clone());
406        (self.clone(), r_as_int)
407    }
408
409    fn wrapping_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
410        let r_as_int = Int::from(r.0.clone());
411        (self.clone(), r_as_int)
412    }
413}
414
415impl Promote<Int> for Uint {
416    type Output = Int;
417
418    fn checked_promote(&self, r: &Int) -> Option<(Self::Output, Self::Output)> {
419        let l_as_int = Int::from(self.0.clone());
420        Some((l_as_int, r.clone()))
421    }
422
423    fn saturating_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
424        let l_as_int = Int::from(self.0.clone());
425        (l_as_int, r.clone())
426    }
427
428    fn wrapping_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
429        let l_as_int = Int::from(self.0.clone());
430        (l_as_int, r.clone())
431    }
432}
433
434impl Promote<Decimal> for Int {
435    type Output = Decimal;
436
437    fn checked_promote(&self, r: &Decimal) -> Option<(Self::Output, Self::Output)> {
438        let l_as_decimal = Decimal::from(self.clone());
439        Some((l_as_decimal, r.clone()))
440    }
441
442    fn saturating_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
443        let l_as_decimal = Decimal::from(self.clone());
444        (l_as_decimal, r.clone())
445    }
446
447    fn wrapping_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
448        let l_as_decimal = Decimal::from(self.clone());
449        (l_as_decimal, r.clone())
450    }
451}
452
453impl Promote<Int> for Decimal {
454    type Output = Decimal;
455
456    fn checked_promote(&self, r: &Int) -> Option<(Self::Output, Self::Output)> {
457        let r_as_decimal = Decimal::from(r.clone());
458        Some((self.clone(), r_as_decimal))
459    }
460
461    fn saturating_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
462        let r_as_decimal = Decimal::from(r.clone());
463        (self.clone(), r_as_decimal)
464    }
465
466    fn wrapping_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
467        let r_as_decimal = Decimal::from(r.clone());
468        (self.clone(), r_as_decimal)
469    }
470}
471
472impl Promote<Decimal> for Uint {
473    type Output = Decimal;
474
475    fn checked_promote(&self, r: &Decimal) -> Option<(Self::Output, Self::Output)> {
476        let l_as_decimal = Decimal::from(self.clone());
477        Some((l_as_decimal, r.clone()))
478    }
479
480    fn saturating_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
481        let l_as_decimal = Decimal::from(self.clone());
482        (l_as_decimal, r.clone())
483    }
484
485    fn wrapping_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
486        let l_as_decimal = Decimal::from(self.clone());
487        (l_as_decimal, r.clone())
488    }
489}
490
491impl Promote<Uint> for Decimal {
492    type Output = Decimal;
493
494    fn checked_promote(&self, r: &Uint) -> Option<(Self::Output, Self::Output)> {
495        let r_as_decimal = Decimal::from(r.clone());
496        Some((self.clone(), r_as_decimal))
497    }
498
499    fn saturating_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
500        let r_as_decimal = Decimal::from(r.clone());
501        (self.clone(), r_as_decimal)
502    }
503
504    fn wrapping_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
505        let r_as_decimal = Decimal::from(r.clone());
506        (self.clone(), r_as_decimal)
507    }
508}
509// Float to Int, Uint, Decimal promotions
510impl Promote<Int> for f32 {
511    type Output = Decimal;
512    
513    fn checked_promote(&self, r: &Int) -> Option<(Self::Output, Self::Output)> {
514        if self.is_finite() {
515            Some((Decimal::from(*self), Decimal::from(r.clone())))
516        } else {
517            None
518        }
519    }
520    
521    fn saturating_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
522        let l_as_decimal = if self.is_finite() {
523            Decimal::from(*self)
524        } else {
525            Decimal::zero()
526        };
527        (l_as_decimal, Decimal::from(r.clone()))
528    }
529    
530    fn wrapping_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
531        let l_as_decimal = if self.is_finite() {
532            Decimal::from(*self)
533        } else {
534            Decimal::zero()
535        };
536        (l_as_decimal, Decimal::from(r.clone()))
537    }
538}
539
540impl Promote<f32> for Int {
541    type Output = Decimal;
542    
543    fn checked_promote(&self, r: &f32) -> Option<(Self::Output, Self::Output)> {
544        if r.is_finite() {
545            Some((Decimal::from(self.clone()), Decimal::from(*r)))
546        } else {
547            None
548        }
549    }
550    
551    fn saturating_promote(&self, r: &f32) -> (Self::Output, Self::Output) {
552        let r_as_decimal = if r.is_finite() {
553            Decimal::from(*r)
554        } else {
555            Decimal::zero()
556        };
557        (Decimal::from(self.clone()), r_as_decimal)
558    }
559    
560    fn wrapping_promote(&self, r: &f32) -> (Self::Output, Self::Output) {
561        let r_as_decimal = if r.is_finite() {
562            Decimal::from(*r)
563        } else {
564            Decimal::zero()
565        };
566        (Decimal::from(self.clone()), r_as_decimal)
567    }
568}
569
570impl Promote<Uint> for f32 {
571    type Output = Decimal;
572    
573    fn checked_promote(&self, r: &Uint) -> Option<(Self::Output, Self::Output)> {
574        if self.is_finite() {
575            Some((Decimal::from(*self), Decimal::from(r.clone())))
576        } else {
577            None
578        }
579    }
580    
581    fn saturating_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
582        let l_as_decimal = if self.is_finite() {
583            Decimal::from(*self)
584        } else {
585            Decimal::zero()
586        };
587        (l_as_decimal, Decimal::from(r.clone()))
588    }
589    
590    fn wrapping_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
591        let l_as_decimal = if self.is_finite() {
592            Decimal::from(*self)
593        } else {
594            Decimal::zero()
595        };
596        (l_as_decimal, Decimal::from(r.clone()))
597    }
598}
599
600impl Promote<f32> for Uint {
601    type Output = Decimal;
602    
603    fn checked_promote(&self, r: &f32) -> Option<(Self::Output, Self::Output)> {
604        if r.is_finite() {
605            Some((Decimal::from(self.clone()), Decimal::from(*r)))
606        } else {
607            None
608        }
609    }
610    
611    fn saturating_promote(&self, r: &f32) -> (Self::Output, Self::Output) {
612        let r_as_decimal = if r.is_finite() {
613            Decimal::from(*r)
614        } else {
615            Decimal::zero()
616        };
617        (Decimal::from(self.clone()), r_as_decimal)
618    }
619    
620    fn wrapping_promote(&self, r: &f32) -> (Self::Output, Self::Output) {
621        let r_as_decimal = if r.is_finite() {
622            Decimal::from(*r)
623        } else {
624            Decimal::zero()
625        };
626        (Decimal::from(self.clone()), r_as_decimal)
627    }
628}
629
630impl Promote<Decimal> for f32 {
631    type Output = Decimal;
632    
633    fn checked_promote(&self, r: &Decimal) -> Option<(Self::Output, Self::Output)> {
634        if self.is_finite() {
635            Some((Decimal::from(*self), r.clone()))
636        } else {
637            None
638        }
639    }
640    
641    fn saturating_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
642        let l_as_decimal = if self.is_finite() {
643            Decimal::from(*self)
644        } else {
645            Decimal::zero()
646        };
647        (l_as_decimal, r.clone())
648    }
649    
650    fn wrapping_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
651        let l_as_decimal = if self.is_finite() {
652            Decimal::from(*self)
653        } else {
654            Decimal::zero()
655        };
656        (l_as_decimal, r.clone())
657    }
658}
659
660impl Promote<f32> for Decimal {
661    type Output = Decimal;
662    
663    fn checked_promote(&self, r: &f32) -> Option<(Self::Output, Self::Output)> {
664        if r.is_finite() {
665            Some((self.clone(), Decimal::from(*r)))
666        } else {
667            None
668        }
669    }
670    
671    fn saturating_promote(&self, r: &f32) -> (Self::Output, Self::Output) {
672        let r_as_decimal = if r.is_finite() {
673            Decimal::from(*r)
674        } else {
675            Decimal::zero()
676        };
677        (self.clone(), r_as_decimal)
678    }
679    
680    fn wrapping_promote(&self, r: &f32) -> (Self::Output, Self::Output) {
681        let r_as_decimal = if r.is_finite() {
682            Decimal::from(*r)
683        } else {
684            Decimal::zero()
685        };
686        (self.clone(), r_as_decimal)
687    }
688}
689
690// f64 implementations
691impl Promote<Int> for f64 {
692    type Output = Decimal;
693    
694    fn checked_promote(&self, r: &Int) -> Option<(Self::Output, Self::Output)> {
695        if self.is_finite() {
696            Some((Decimal::from(*self), Decimal::from(r.clone())))
697        } else {
698            None
699        }
700    }
701    
702    fn saturating_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
703        let l_as_decimal = if self.is_finite() {
704            Decimal::from(*self)
705        } else {
706            Decimal::zero()
707        };
708        (l_as_decimal, Decimal::from(r.clone()))
709    }
710    
711    fn wrapping_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
712        let l_as_decimal = if self.is_finite() {
713            Decimal::from(*self)
714        } else {
715            Decimal::zero()
716        };
717        (l_as_decimal, Decimal::from(r.clone()))
718    }
719}
720
721impl Promote<f64> for Int {
722    type Output = Decimal;
723    
724    fn checked_promote(&self, r: &f64) -> Option<(Self::Output, Self::Output)> {
725        if r.is_finite() {
726            let l_as_decimal = Decimal::from(self.clone());
727            let r_as_decimal = Decimal::from(*r);
728            Some((l_as_decimal, r_as_decimal))
729        } else {
730            None
731        }
732    }
733    
734    fn saturating_promote(&self, r: &f64) -> (Self::Output, Self::Output) {
735        let l_as_decimal = Decimal::from(self.clone());
736        let r_as_decimal = if r.is_finite() {
737            Decimal::from(*r)
738        } else {
739            Decimal::zero()
740        };
741        (l_as_decimal, r_as_decimal)
742    }
743    
744    fn wrapping_promote(&self, r: &f64) -> (Self::Output, Self::Output) {
745        let l_as_decimal = Decimal::from(self.clone());
746        let r_as_decimal = if r.is_finite() {
747            Decimal::from(*r)
748        } else {
749            Decimal::zero()
750        };
751        (l_as_decimal, r_as_decimal)
752    }
753}
754
755impl Promote<Uint> for f64 {
756    type Output = Decimal;
757    
758    fn checked_promote(&self, r: &Uint) -> Option<(Self::Output, Self::Output)> {
759        if self.is_finite() {
760            let l_as_decimal = Decimal::from(*self);
761            let r_as_decimal = Decimal::from(r.clone());
762            Some((l_as_decimal, r_as_decimal))
763        } else {
764            None
765        }
766    }
767    
768    fn saturating_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
769        let l_as_decimal = if self.is_finite() {
770            Decimal::from(*self)
771        } else {
772            Decimal::zero()
773        };
774        let r_as_decimal = Decimal::from(r.clone());
775        (l_as_decimal, r_as_decimal)
776    }
777    
778    fn wrapping_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
779        let l_as_decimal = if self.is_finite() {
780            Decimal::from(*self)
781        } else {
782            Decimal::zero()
783        };
784        let r_as_decimal = Decimal::from(r.clone());
785        (l_as_decimal, r_as_decimal)
786    }
787}
788
789impl Promote<f64> for Uint {
790    type Output = Decimal;
791    
792    fn checked_promote(&self, r: &f64) -> Option<(Self::Output, Self::Output)> {
793        if r.is_finite() {
794            let l_as_decimal = Decimal::from(self.clone());
795            let r_as_decimal = Decimal::from(*r);
796            Some((l_as_decimal, r_as_decimal))
797        } else {
798            None
799        }
800    }
801    
802    fn saturating_promote(&self, r: &f64) -> (Self::Output, Self::Output) {
803        let l_as_decimal = Decimal::from(self.clone());
804        let r_as_decimal = if r.is_finite() {
805            Decimal::from(*r)
806        } else {
807            Decimal::zero()
808        };
809        (l_as_decimal, r_as_decimal)
810    }
811    
812    fn wrapping_promote(&self, r: &f64) -> (Self::Output, Self::Output) {
813        let l_as_decimal = Decimal::from(self.clone());
814        let r_as_decimal = if r.is_finite() {
815            Decimal::from(*r)
816        } else {
817            Decimal::zero()
818        };
819        (l_as_decimal, r_as_decimal)
820    }
821}
822
823impl Promote<Decimal> for f64 {
824    type Output = Decimal;
825    
826    fn checked_promote(&self, r: &Decimal) -> Option<(Self::Output, Self::Output)> {
827        if self.is_finite() {
828            let l_as_decimal = Decimal::from(*self);
829            Some((l_as_decimal, r.clone()))
830        } else {
831            None
832        }
833    }
834    
835    fn saturating_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
836        let l_as_decimal = if self.is_finite() {
837            Decimal::from(*self)
838        } else {
839            Decimal::zero()
840        };
841        (l_as_decimal, r.clone())
842    }
843    
844    fn wrapping_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
845        let l_as_decimal = if self.is_finite() {
846            Decimal::from(*self)
847        } else {
848            Decimal::zero()
849        };
850        (l_as_decimal, r.clone())
851    }
852}
853
854impl Promote<f64> for Decimal {
855    type Output = Decimal;
856    
857    fn checked_promote(&self, r: &f64) -> Option<(Self::Output, Self::Output)> {
858        if r.is_finite() {
859            let r_as_decimal = Decimal::from(*r);
860            Some((self.clone(), r_as_decimal))
861        } else {
862            None
863        }
864    }
865    
866    fn saturating_promote(&self, r: &f64) -> (Self::Output, Self::Output) {
867        let r_as_decimal = if r.is_finite() {
868            Decimal::from(*r)
869        } else {
870            Decimal::zero()
871        };
872        (self.clone(), r_as_decimal)
873    }
874    
875    fn wrapping_promote(&self, r: &f64) -> (Self::Output, Self::Output) {
876        let r_as_decimal = if r.is_finite() {
877            Decimal::from(*r)
878        } else {
879            Decimal::zero()
880        };
881        (self.clone(), r_as_decimal)
882    }
883}
884
885// Promote implementations for integer types with Int
886macro_rules! impl_promote_int_to_int {
887    ($($t:ty),*) => {
888        $(
889            impl Promote<Int> for $t {
890                type Output = Int;
891                
892                fn checked_promote(&self, r: &Int) -> Option<(Self::Output, Self::Output)> {
893                    Some((Int::from(*self), r.clone()))
894                }
895                
896                fn saturating_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
897                    (Int::from(*self), r.clone())
898                }
899                
900                fn wrapping_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
901                    (Int::from(*self), r.clone())
902                }
903            }
904            
905            impl Promote<$t> for Int {
906                type Output = Int;
907                
908                fn checked_promote(&self, r: &$t) -> Option<(Self::Output, Self::Output)> {
909                    Some((self.clone(), Int::from(*r)))
910                }
911                
912                fn saturating_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
913                    (self.clone(), Int::from(*r))
914                }
915                
916                fn wrapping_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
917                    (self.clone(), Int::from(*r))
918                }
919            }
920        )*
921    }
922}
923
924impl_promote_int_to_int!(i8, i16, i32, i64, i128);
925
926// Promote implementations for unsigned integer types with Uint
927macro_rules! impl_promote_uint_to_uint {
928    ($($t:ty),*) => {
929        $(
930            impl Promote<Uint> for $t {
931                type Output = Uint;
932                
933                fn checked_promote(&self, r: &Uint) -> Option<(Self::Output, Self::Output)> {
934                    Some((Uint::from(*self), r.clone()))
935                }
936                
937                fn saturating_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
938                    (Uint::from(*self), r.clone())
939                }
940                
941                fn wrapping_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
942                    (Uint::from(*self), r.clone())
943                }
944            }
945            
946            impl Promote<$t> for Uint {
947                type Output = Uint;
948                
949                fn checked_promote(&self, r: &$t) -> Option<(Self::Output, Self::Output)> {
950                    Some((self.clone(), Uint::from(*r)))
951                }
952                
953                fn saturating_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
954                    (self.clone(), Uint::from(*r))
955                }
956                
957                fn wrapping_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
958                    (self.clone(), Uint::from(*r))
959                }
960            }
961        )*
962    }
963}
964
965impl_promote_uint_to_uint!(u8, u16, u32, u64, u128);
966
967// Promote implementations for unsigned integers with Int (promotes to Int)
968macro_rules! impl_promote_uint_to_int {
969    ($($t:ty),*) => {
970        $(
971            impl Promote<Int> for $t {
972                type Output = Int;
973                
974                fn checked_promote(&self, r: &Int) -> Option<(Self::Output, Self::Output)> {
975                    Some((Int::from(*self), r.clone()))
976                }
977                
978                fn saturating_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
979                    (Int::from(*self), r.clone())
980                }
981                
982                fn wrapping_promote(&self, r: &Int) -> (Self::Output, Self::Output) {
983                    (Int::from(*self), r.clone())
984                }
985            }
986            
987            impl Promote<$t> for Int {
988                type Output = Int;
989                
990                fn checked_promote(&self, r: &$t) -> Option<(Self::Output, Self::Output)> {
991                    Some((self.clone(), Int::from(*r)))
992                }
993                
994                fn saturating_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
995                    (self.clone(), Int::from(*r))
996                }
997                
998                fn wrapping_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
999                    (self.clone(), Int::from(*r))
1000                }
1001            }
1002        )*
1003    }
1004}
1005
1006impl_promote_uint_to_int!(u8, u16, u32, u64, u128);
1007
1008// Promote implementations for signed integers with Uint (promotes to Int)
1009macro_rules! impl_promote_int_to_uint {
1010    ($($t:ty),*) => {
1011        $(
1012            impl Promote<Uint> for $t {
1013                type Output = Int;
1014                
1015                fn checked_promote(&self, r: &Uint) -> Option<(Self::Output, Self::Output)> {
1016                    Some((Int::from(*self), Int(r.0.clone())))
1017                }
1018                
1019                fn saturating_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
1020                    (Int::from(*self), Int(r.0.clone()))
1021                }
1022                
1023                fn wrapping_promote(&self, r: &Uint) -> (Self::Output, Self::Output) {
1024                    (Int::from(*self), Int(r.0.clone()))
1025                }
1026            }
1027            
1028            impl Promote<$t> for Uint {
1029                type Output = Int;
1030                
1031                fn checked_promote(&self, r: &$t) -> Option<(Self::Output, Self::Output)> {
1032                    Some((Int(self.0.clone()), Int::from(*r)))
1033                }
1034                
1035                fn saturating_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
1036                    (Int(self.0.clone()), Int::from(*r))
1037                }
1038                
1039                fn wrapping_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
1040                    (Int(self.0.clone()), Int::from(*r))
1041                }
1042            }
1043        )*
1044    }
1045}
1046
1047impl_promote_int_to_uint!(i8, i16, i32, i64, i128);
1048
1049// Promote implementations for all integer types with Decimal
1050macro_rules! impl_promote_int_to_decimal {
1051    ($($t:ty),*) => {
1052        $(
1053            impl Promote<Decimal> for $t {
1054                type Output = Decimal;
1055                
1056                fn checked_promote(&self, r: &Decimal) -> Option<(Self::Output, Self::Output)> {
1057                    Some((Decimal::from(*self), r.clone()))
1058                }
1059                
1060                fn saturating_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
1061                    (Decimal::from(*self), r.clone())
1062                }
1063                
1064                fn wrapping_promote(&self, r: &Decimal) -> (Self::Output, Self::Output) {
1065                    (Decimal::from(*self), r.clone())
1066                }
1067            }
1068            
1069            impl Promote<$t> for Decimal {
1070                type Output = Decimal;
1071                
1072                fn checked_promote(&self, r: &$t) -> Option<(Self::Output, Self::Output)> {
1073                    Some((self.clone(), Decimal::from(*r)))
1074                }
1075                
1076                fn saturating_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
1077                    (self.clone(), Decimal::from(*r))
1078                }
1079                
1080                fn wrapping_promote(&self, r: &$t) -> (Self::Output, Self::Output) {
1081                    (self.clone(), Decimal::from(*r))
1082                }
1083            }
1084        )*
1085    }
1086}
1087
1088impl_promote_int_to_decimal!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128);