1#![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
127impl_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
141impl_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
155macro_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}
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);