1#![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
126impl_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
140impl_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
154macro_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}
509impl 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
690impl 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
885macro_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
926macro_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
967macro_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
1008macro_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
1049macro_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);