Skip to main content

reifydb_type/value/number/
promote.rs

1// SPDX-License-Identifier: MIT
2// Copyright (c) 2025 ReifyDB
3
4
5#![cfg_attr(rustfmt, rustfmt_skip)]
6
7use crate::value::is::IsNumber;
8
9pub trait Promote<R> where Self: IsNumber, R: IsNumber {
10    type Output: IsNumber;
11    fn checked_promote(&self, r: &R) -> Option<(Self::Output, Self::Output)>;
12    fn saturating_promote(&self, r: &R) -> (Self::Output, Self::Output);
13    fn wrapping_promote(&self, r: &R) -> (Self::Output, Self::Output);
14
15}
16
17macro_rules! impl_promote_float_float {
18    ($l:ty, $r:ty => $common:ty) => {
19        impl Promote<$r> for $l {
20            type Output = $common;
21
22            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)> {
23                if self.is_finite() && r.is_finite() {
24                    Some((*self as $common, *r as $common))
25                } else {
26                    None
27                }
28            }
29
30            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
31                let l = if self.is_finite() {
32                    *self as $common
33                } else if self.is_sign_negative() {
34                    <$common>::MIN
35                } else {
36                    <$common>::MAX
37                };
38                let r = if r.is_finite() {
39                    *r as $common
40                } else if r.is_sign_negative() {
41                    <$common>::MIN
42                } else {
43                    <$common>::MAX
44                };
45                (l, r)
46            }
47
48            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
49                (*self as $common, *r as $common)
50            }
51        }
52    };
53}
54
55macro_rules! impl_promote_float_integer {
56    ($l:ty, $r:ty => $common:ty) => {
57        impl Promote<$r> for $l {
58            type Output = $common;
59
60            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)> {
61                if self.is_finite() {
62                    Some((*self as $common, *r as $common))
63                } else {
64                    None
65                }
66            }
67
68            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
69                let l = if self.is_finite() {
70                    *self as $common
71                } else if self.is_sign_negative() {
72                    <$common>::MIN
73                } else {
74                    <$common>::MAX
75                };
76
77                let r = *r as $common;
78                (l, r)
79            }
80
81            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
82                (*self as $common, *r as $common)
83            }
84        }
85    };
86}
87
88
89macro_rules! impl_promote_integer_float {
90    ($l:ty, $r:ty => $common:ty) => {
91        impl Promote<$r> for $l {
92            type Output = $common;
93
94            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)> {
95                if r.is_finite() {
96                    Some((*self as $common, *r as $common))
97                } else {
98                    None
99                }
100            }
101
102            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
103                let l = *self as $common;
104                let r = if r.is_finite() {
105                    *r as $common
106                } else if r.is_sign_negative() {
107                    <$common>::MIN
108                } else {
109                    <$common>::MAX
110                };
111                (l, r)
112            }
113
114            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
115                (*self as $common, *r as $common)
116            }
117        }
118    };
119}
120
121
122
123impl_promote_float_float!(f32, f32 => f64);
124impl_promote_float_float!(f32, f64 => f64); impl_promote_float_float!(f64, f32 => f64);
125impl_promote_float_float!(f64, f64 => f64);
126
127// float - signed
128
129impl_promote_float_integer!(f32, i8 => f64); impl_promote_integer_float!(i8, f32 => f64);
130impl_promote_float_integer!(f32, i16 => f64); impl_promote_integer_float!(i16, f32 => f64);
131impl_promote_float_integer!(f32, i32 => f64); impl_promote_integer_float!(i32, f32 => f64);
132impl_promote_float_integer!(f32, i64 => f64); impl_promote_integer_float!(i64, f32 => f64);
133impl_promote_float_integer!(f32, i128 => f64); impl_promote_integer_float!(i128, f32 => f64);
134
135impl_promote_float_integer!(f64, i8 => f64); impl_promote_integer_float!(i8, f64 => f64);
136impl_promote_float_integer!(f64, i16 => f64); impl_promote_integer_float!(i16, f64 => f64);
137impl_promote_float_integer!(f64, i32 => f64); impl_promote_integer_float!(i32, f64 => f64);
138impl_promote_float_integer!(f64, i64 => f64); impl_promote_integer_float!(i64, f64 => f64);
139impl_promote_float_integer!(f64, i128 => f64); impl_promote_integer_float!(i128, f64 => f64);
140
141// float - unsigned
142
143impl_promote_float_integer!(f32, u8 => f64); impl_promote_integer_float!(u8, f32 => f64);
144impl_promote_float_integer!(f32, u16 => f64); impl_promote_integer_float!(u16, f32 => f64);
145impl_promote_float_integer!(f32, u32 => f64); impl_promote_integer_float!(u32, f32 => f64);
146impl_promote_float_integer!(f32, u64 => f64); impl_promote_integer_float!(u64, f32 => f64);
147impl_promote_float_integer!(f32, u128 => f64); impl_promote_integer_float!(u128, f32 => f64);
148
149impl_promote_float_integer!(f64, u8 => f64); impl_promote_integer_float!(u8, f64 => f64);
150impl_promote_float_integer!(f64, u16 => f64); impl_promote_integer_float!(u16, f64 => f64);
151impl_promote_float_integer!(f64, u32 => f64); impl_promote_integer_float!(u32, f64 => f64);
152impl_promote_float_integer!(f64, u64 => f64); impl_promote_integer_float!(u64, f64 => f64);
153impl_promote_float_integer!(f64, u128 => f64); impl_promote_integer_float!(u128, f64 => f64);
154
155// signed - signed 
156macro_rules! impl_promote_signed_signed {
157    ($l:ty, $r:ty => $common:ty) => {
158        impl Promote<$r> for $l {
159            type Output = $common;
160
161            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)>{
162                let l: Option<$common> = <$common>::try_from(*self).ok();
163                let r: Option<$common> = <$common>::try_from(*r).ok();
164                match(l,r){
165                    (Some(l),Some(r)) => Some((l,r)),
166                    _ => None
167                }
168            }
169
170            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
171                let l = match <$common>::try_from(*self) {
172                    Ok(v) => v,
173                    Err(_) => if *self < 0 { <$common>::MIN } else { <$common>::MAX }};
174                let r = match <$common>::try_from(*r) {
175                    Ok(v) => v,
176                    Err(_) => if *r < 0 { <$common>::MIN } else { <$common>::MAX }};
177                (l, r)
178            }
179
180            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
181                (*self as $common, *r as $common)
182            }
183        }
184    };
185}
186impl_promote_signed_signed!(i8, i8 => i128);
187impl_promote_signed_signed!(i8, i16 => i128); impl_promote_signed_signed!(i16, i8 => i128);
188impl_promote_signed_signed!(i8, i32 => i128); impl_promote_signed_signed!(i32, i8 => i128);
189impl_promote_signed_signed!(i8, i64 => i128); impl_promote_signed_signed!(i64, i8 => i128);
190impl_promote_signed_signed!(i8, i128 => i128); impl_promote_signed_signed!(i128, i8 => i128);
191
192impl_promote_signed_signed!(i16, i16 => i128);
193impl_promote_signed_signed!(i16, i32 => i128); impl_promote_signed_signed!(i32, i16 => i128);
194impl_promote_signed_signed!(i16, i64 => i128); impl_promote_signed_signed!(i64, i16 => i128);
195impl_promote_signed_signed!(i16, i128 => i128); impl_promote_signed_signed!(i128, i16 => i128);
196
197impl_promote_signed_signed!(i32, i32 => i128);
198impl_promote_signed_signed!(i32, i64 => i128); impl_promote_signed_signed!(i64, i32 => i128);
199impl_promote_signed_signed!(i32, i128 => i128); impl_promote_signed_signed!(i128, i32 => i128);
200
201impl_promote_signed_signed!(i64, i64 => i128);
202impl_promote_signed_signed!(i64, i128 => i128); impl_promote_signed_signed!(i128, i64 => i128);
203
204impl_promote_signed_signed!(i128, i128 => i128);
205
206macro_rules! impl_promote_unsigned_unsigned {
207    ($l:ty, $r:ty => $common:ty) => {
208        impl Promote<$r> for $l {
209            type Output = $common;
210
211            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)>{
212                let l: Option<$common> = <$common>::try_from(*self).ok();
213                let r: Option<$common> = <$common>::try_from(*r).ok();
214                match(l,r){
215                    (Some(l),Some(r)) => Some((l,r)),
216                    _ => None
217                }
218            }
219
220            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
221                let l = match <$common>::try_from(*self) {
222                    Ok(v) => v,
223                    Err(_) =>  <$common>::MAX};
224                let r = match <$common>::try_from(*r) {
225                    Ok(v) => v,
226                    Err(_) => <$common>::MAX};
227                (l, r)
228            }
229
230            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
231                (*self as $common, *r as $common)
232            }
233        }
234    };
235}
236
237impl_promote_unsigned_unsigned!(u8, u8 => u128);
238impl_promote_unsigned_unsigned!(u8, u16 => u128); impl_promote_unsigned_unsigned!(u16, u8 => u128);
239impl_promote_unsigned_unsigned!(u8, u32 => u128); impl_promote_unsigned_unsigned!(u32, u8 => u128);
240impl_promote_unsigned_unsigned!(u8, u64 => u128); impl_promote_unsigned_unsigned!(u64, u8 => u128);
241impl_promote_unsigned_unsigned!(u8, u128 => u128); impl_promote_unsigned_unsigned!(u128, u8 => u128);
242
243impl_promote_unsigned_unsigned!(u16, u16 => u128);
244impl_promote_unsigned_unsigned!(u16, u32 => u128); impl_promote_unsigned_unsigned!(u32, u16 => u128);
245impl_promote_unsigned_unsigned!(u16, u64 => u128); impl_promote_unsigned_unsigned!(u64, u16 => u128);
246impl_promote_unsigned_unsigned!(u16, u128 => u128); impl_promote_unsigned_unsigned!(u128, u16 => u128);
247
248impl_promote_unsigned_unsigned!(u32, u32 => u128);
249impl_promote_unsigned_unsigned!(u32, u64 => u128); impl_promote_unsigned_unsigned!(u64, u32 => u128);
250impl_promote_unsigned_unsigned!(u32, u128 => u128); impl_promote_unsigned_unsigned!(u128, u32 => u128);
251
252impl_promote_unsigned_unsigned!(u64, u64 => u128);
253impl_promote_unsigned_unsigned!(u64, u128 => u128); impl_promote_unsigned_unsigned!(u128, u64 => u128);
254
255impl_promote_unsigned_unsigned!(u128, u128 => u128);
256
257
258macro_rules! impl_promote_signed_unsigned {
259    ($l:ty, $r:ty => $common:ty) => {
260        impl Promote<$r> for $l {
261            type Output = $common;
262
263            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)>{
264                let l: Option<$common> = <$common>::try_from(*self).ok();
265                let r: Option<$common> = <$common>::try_from(*r).ok();
266                match(l,r){
267                    (Some(l),Some(r)) => Some((l,r)),
268                    _ => None
269                }
270            }
271
272            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
273                let l = match <$common>::try_from(*self) {
274                    Ok(v) => v,
275                    Err(_) => if *self < 0 { <$common>::MIN } else { <$common>::MAX }};
276                let r = match <$common>::try_from(*r) {
277                    Ok(v) => v,
278                    Err(_) => <$common>::MAX};
279                (l, r)
280            }
281
282            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
283                (*self as $common, *r as $common)
284            }
285        }
286    };
287}
288
289macro_rules! impl_promote_unsigned_signed {
290    ($l:ty, $r:ty => $common:ty) => {
291        impl Promote<$r> for $l {
292            type Output = $common;
293
294            fn checked_promote(&self, r: &$r) -> Option<(Self::Output, Self::Output)>{
295                let l: Option<$common> = <$common>::try_from(*self).ok();
296                let r: Option<$common> = <$common>::try_from(*r).ok();
297                match(l,r){
298                    (Some(l),Some(r)) => Some((l,r)),
299                    _ => None
300                }
301            }
302
303            fn saturating_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
304                let l = match <$common>::try_from(*self) {
305                    Ok(v) => v,
306                    Err(_) => <$common>::MAX};
307                let r = match <$common>::try_from(*r) {
308                    Ok(v) => v,
309                    Err(_) => if *r < 0 { <$common>::MIN } else { <$common>::MAX }};
310                (l, r)
311            }
312
313            fn wrapping_promote(&self, r: &$r) -> (Self::Output, Self::Output) {
314                (*self as $common, *r as $common)
315            }
316        }
317    };
318}
319
320impl_promote_signed_unsigned!(i8, u8 => i128);    impl_promote_unsigned_signed!(u8, i8 => i128);
321impl_promote_signed_unsigned!(i8, u16 => i128);   impl_promote_unsigned_signed!(u16, i8 => i128);
322impl_promote_signed_unsigned!(i8, u32 => i128);   impl_promote_unsigned_signed!(u32, i8 => i128);
323impl_promote_signed_unsigned!(i8, u64 => i128);   impl_promote_unsigned_signed!(u64, i8 => i128);
324impl_promote_signed_unsigned!(i8, u128 => i128);  impl_promote_unsigned_signed!(u128, i8 => i128);
325impl_promote_signed_unsigned!(i16, u8 => i128);   impl_promote_unsigned_signed!(u8, i16 => i128);
326impl_promote_signed_unsigned!(i16, u16 => i128);  impl_promote_unsigned_signed!(u16, i16 => i128);
327impl_promote_signed_unsigned!(i16, u32 => i128);  impl_promote_unsigned_signed!(u32, i16 => i128);
328impl_promote_signed_unsigned!(i16, u64 => i128);  impl_promote_unsigned_signed!(u64, i16 => i128);
329impl_promote_signed_unsigned!(i16, u128 => i128); impl_promote_unsigned_signed!(u128, i16 => i128);
330impl_promote_signed_unsigned!(i32, u8 => i128);   impl_promote_unsigned_signed!(u8, i32 => i128);
331impl_promote_signed_unsigned!(i32, u16 => i128);  impl_promote_unsigned_signed!(u16, i32 => i128);
332impl_promote_signed_unsigned!(i32, u32 => i128);  impl_promote_unsigned_signed!(u32, i32 => i128);
333impl_promote_signed_unsigned!(i32, u64 => i128);  impl_promote_unsigned_signed!(u64, i32 => i128);
334impl_promote_signed_unsigned!(i32, u128 => i128); impl_promote_unsigned_signed!(u128, i32 => i128);
335impl_promote_signed_unsigned!(i64, u8 => i128);   impl_promote_unsigned_signed!(u8, i64 => i128);
336impl_promote_signed_unsigned!(i64, u16 => i128);  impl_promote_unsigned_signed!(u16, i64 => i128);
337impl_promote_signed_unsigned!(i64, u32 => i128);  impl_promote_unsigned_signed!(u32, i64 => i128);
338impl_promote_signed_unsigned!(i64, u64 => i128);  impl_promote_unsigned_signed!(u64, i64 => i128);
339impl_promote_signed_unsigned!(i64, u128 => i128); impl_promote_unsigned_signed!(u128, i64 => i128);
340impl_promote_signed_unsigned!(i128, u8 => i128);   impl_promote_unsigned_signed!(u8, i128 => i128);
341impl_promote_signed_unsigned!(i128, u16 => i128);  impl_promote_unsigned_signed!(u16, i128 => i128);
342impl_promote_signed_unsigned!(i128, u32 => i128);  impl_promote_unsigned_signed!(u32, i128 => i128);
343impl_promote_signed_unsigned!(i128, u64 => i128);  impl_promote_unsigned_signed!(u64, i128 => i128);
344impl_promote_signed_unsigned!(i128, u128 => i128); impl_promote_unsigned_signed!(u128, i128 => i128);
345
346use crate::value::{decimal::Decimal, 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);