1use std::cmp::Ordering;
17use std::fmt;
18use std::hash::{Hash, Hasher};
19use std::iter::{Product, Sum};
20use std::ops::{
21 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
22};
23use std::str::FromStr;
24
25#[cfg(feature = "serde")]
26use serde::{Deserialize, Serialize};
27
28use crate::context::Context;
29use crate::decimal::Decimal;
30use crate::decimal128::Decimal128;
31use crate::decimal32::Decimal32;
32use crate::decimal64::Decimal64;
33use crate::error::ParseDecimalError;
34
35#[derive(Debug, Clone, Copy)]
57#[repr(transparent)]
58#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
59pub struct OrderedDecimal<D>(pub D);
60
61impl<D> OrderedDecimal<D> {
62 pub fn into_inner(self) -> D {
64 self.0
65 }
66}
67
68impl<D> fmt::Display for OrderedDecimal<D>
69where
70 D: fmt::Display,
71{
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73 self.0.fmt(f)
74 }
75}
76
77impl<D> PartialOrd for OrderedDecimal<D>
78where
79 Self: Ord,
80{
81 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
82 Some(self.cmp(other))
83 }
84}
85
86impl<D> PartialEq for OrderedDecimal<D>
87where
88 Self: Ord,
89{
90 fn eq(&self, other: &Self) -> bool {
91 self.cmp(other) == Ordering::Equal
92 }
93}
94
95impl<D> Eq for OrderedDecimal<D> where Self: Ord {}
96
97impl Ord for OrderedDecimal<Decimal64> {
98 fn cmp(&self, other: &Self) -> Ordering {
99 let mut cx = Context::<Decimal64>::default();
100 let lhs = cx.reduce(self.0);
101 let rhs = cx.reduce(other.0);
102 match cx.partial_cmp(lhs, rhs) {
103 Some(ordering) => ordering,
104 None => {
105 if lhs.is_nan() {
106 if rhs.is_nan() {
107 Ordering::Equal
108 } else {
109 Ordering::Greater
110 }
111 } else {
112 Ordering::Less
113 }
114 }
115 }
116 }
117}
118
119impl Hash for OrderedDecimal<Decimal64> {
120 fn hash<H>(&self, state: &mut H)
121 where
122 H: Hasher,
123 {
124 let d = if self.0.is_nan() {
125 Decimal64::NAN
126 } else if self.0.is_zero() {
127 Decimal64::ZERO
128 } else {
129 Context::<Decimal64>::default().reduce(self.0)
130 };
131 d.inner.bytes.hash(state)
132 }
133}
134
135impl Ord for OrderedDecimal<Decimal128> {
136 fn cmp(&self, other: &Self) -> Ordering {
137 let mut cx = Context::<Decimal128>::default();
138 let lhs = cx.reduce(self.0);
139 let rhs = cx.reduce(other.0);
140 match cx.partial_cmp(lhs, rhs) {
141 Some(ordering) => ordering,
142 None => {
143 if lhs.is_nan() {
144 if rhs.is_nan() {
145 Ordering::Equal
146 } else {
147 Ordering::Greater
148 }
149 } else {
150 Ordering::Less
151 }
152 }
153 }
154 }
155}
156
157impl Hash for OrderedDecimal<Decimal128> {
158 fn hash<H>(&self, state: &mut H)
159 where
160 H: Hasher,
161 {
162 let d = if self.0.is_nan() {
163 Decimal128::NAN
164 } else if self.0.is_zero() {
165 Decimal128::ZERO
166 } else {
167 Context::<Decimal128>::default().reduce(self.0)
168 };
169 d.inner.bytes.hash(state)
170 }
171}
172
173impl<const N: usize> Ord for OrderedDecimal<Decimal<N>> {
174 fn cmp(&self, other: &Self) -> Ordering {
175 let mut cx = Context::<Decimal<N>>::default();
176 let mut lhs = self.0.clone();
177 let mut rhs = other.0.clone();
178 cx.reduce(&mut lhs);
179 cx.reduce(&mut rhs);
180 match cx.partial_cmp(&lhs, &rhs) {
181 Some(ordering) => ordering,
182 None => {
183 if lhs.is_nan() {
184 if rhs.is_nan() {
185 Ordering::Equal
186 } else {
187 Ordering::Greater
188 }
189 } else {
190 Ordering::Less
191 }
192 }
193 }
194 }
195}
196
197impl<const N: usize> Hash for OrderedDecimal<Decimal<N>> {
198 fn hash<H>(&self, state: &mut H)
199 where
200 H: Hasher,
201 {
202 let d = if self.0.is_nan() {
203 Decimal::<N>::nan()
204 } else if self.0.is_infinite() {
205 let mut d = Decimal::<N>::infinity();
206 if self.0.is_negative() {
207 Context::<Decimal<N>>::default().minus(&mut d);
208 }
209 d
210 } else if self.0.is_zero() {
211 Decimal::<N>::zero()
212 } else {
213 let mut d = self.0.clone();
214 Context::<Decimal<N>>::default().reduce(&mut d);
215 d
216 };
217 d.digits.hash(state);
218 d.exponent.hash(state);
219 d.bits.hash(state);
220 d.coefficient_units().hash(state);
221 }
222}
223
224impl<D> Default for OrderedDecimal<D>
225where
226 D: Default,
227{
228 fn default() -> Self {
229 OrderedDecimal(D::default())
230 }
231}
232
233impl<D> FromStr for OrderedDecimal<D>
234where
235 D: FromStr<Err = ParseDecimalError>,
236{
237 type Err = ParseDecimalError;
238
239 fn from_str(s: &str) -> Result<OrderedDecimal<D>, ParseDecimalError> {
240 Ok(OrderedDecimal(D::from_str(s)?))
241 }
242}
243
244impl<D> From<i32> for OrderedDecimal<D>
245where
246 D: From<i32>,
247{
248 fn from(n: i32) -> OrderedDecimal<D> {
249 OrderedDecimal(D::from(n))
250 }
251}
252
253impl<D> From<u32> for OrderedDecimal<D>
254where
255 D: From<u32>,
256{
257 fn from(n: u32) -> OrderedDecimal<D> {
258 OrderedDecimal(D::from(n))
259 }
260}
261
262impl<D> From<Decimal32> for OrderedDecimal<D>
263where
264 D: From<Decimal32>,
265{
266 fn from(n: Decimal32) -> OrderedDecimal<D> {
267 OrderedDecimal(D::from(n))
268 }
269}
270
271impl<D> From<Decimal64> for OrderedDecimal<D>
272where
273 D: From<Decimal64>,
274{
275 fn from(n: Decimal64) -> OrderedDecimal<D> {
276 OrderedDecimal(D::from(n))
277 }
278}
279
280impl<D> From<Decimal128> for OrderedDecimal<D>
281where
282 D: From<Decimal128>,
283{
284 fn from(n: Decimal128) -> OrderedDecimal<D> {
285 OrderedDecimal(D::from(n))
286 }
287}
288
289impl<D> Add for OrderedDecimal<D>
290where
291 D: Add<Output = D>,
292{
293 type Output = Self;
294
295 fn add(self, other: OrderedDecimal<D>) -> Self {
296 OrderedDecimal(self.0 + other.0)
297 }
298}
299
300impl<D> Add<D> for OrderedDecimal<D>
301where
302 D: Add<Output = D>,
303{
304 type Output = Self;
305
306 fn add(self, other: D) -> Self {
307 OrderedDecimal(self.0 + other)
308 }
309}
310
311impl Add<OrderedDecimal<Decimal64>> for Decimal64 {
312 type Output = Self;
313
314 fn add(self, other: OrderedDecimal<Decimal64>) -> Self {
315 self + other.0
316 }
317}
318
319impl Add<OrderedDecimal<Decimal128>> for Decimal128 {
320 type Output = Self;
321
322 fn add(self, other: OrderedDecimal<Decimal128>) -> Self {
323 self + other.0
324 }
325}
326
327impl<D> AddAssign for OrderedDecimal<D>
328where
329 D: AddAssign,
330{
331 fn add_assign(&mut self, other: Self) {
332 self.0 += other.0;
333 }
334}
335
336impl<D> AddAssign<D> for OrderedDecimal<D>
338where
339 D: Add<Output = D> + Copy,
340{
341 fn add_assign(&mut self, other: D) {
342 *self = *self + other;
343 }
344}
345
346impl<D> Sub for OrderedDecimal<D>
347where
348 D: Sub<Output = D>,
349{
350 type Output = Self;
351
352 fn sub(self, other: OrderedDecimal<D>) -> Self {
353 OrderedDecimal(self.0 - other.0)
354 }
355}
356
357impl<D> Sub<D> for OrderedDecimal<D>
358where
359 D: Sub<Output = D>,
360{
361 type Output = Self;
362
363 fn sub(self, other: D) -> Self {
364 OrderedDecimal(self.0 - other)
365 }
366}
367
368impl Sub<OrderedDecimal<Decimal64>> for Decimal64 {
369 type Output = Self;
370
371 fn sub(self, other: OrderedDecimal<Decimal64>) -> Self {
372 self - other.0
373 }
374}
375
376impl Sub<OrderedDecimal<Decimal128>> for Decimal128 {
377 type Output = Self;
378
379 fn sub(self, other: OrderedDecimal<Decimal128>) -> Self {
380 self - other.0
381 }
382}
383
384impl<D> SubAssign for OrderedDecimal<D>
385where
386 D: SubAssign,
387{
388 fn sub_assign(&mut self, other: Self) {
389 self.0 -= other.0;
390 }
391}
392
393impl<D> SubAssign<D> for OrderedDecimal<D>
395where
396 D: Sub<Output = D> + Copy,
397{
398 fn sub_assign(&mut self, other: D) {
399 *self = *self - other;
400 }
401}
402impl<D> Mul for OrderedDecimal<D>
403where
404 D: Mul<Output = D>,
405{
406 type Output = Self;
407
408 fn mul(self, other: OrderedDecimal<D>) -> Self {
409 OrderedDecimal(self.0 * other.0)
410 }
411}
412
413impl<D> Mul<D> for OrderedDecimal<D>
414where
415 D: Mul<Output = D>,
416{
417 type Output = Self;
418
419 fn mul(self, other: D) -> Self {
420 OrderedDecimal(self.0 * other)
421 }
422}
423
424impl Mul<OrderedDecimal<Decimal64>> for Decimal64 {
425 type Output = Self;
426
427 fn mul(self, other: OrderedDecimal<Decimal64>) -> Self {
428 self * other.0
429 }
430}
431
432impl Mul<OrderedDecimal<Decimal128>> for Decimal128 {
433 type Output = Self;
434
435 fn mul(self, other: OrderedDecimal<Decimal128>) -> Self {
436 self * other.0
437 }
438}
439
440impl<D> MulAssign for OrderedDecimal<D>
441where
442 D: MulAssign,
443{
444 fn mul_assign(&mut self, other: Self) {
445 self.0 *= other.0;
446 }
447}
448
449impl<D> MulAssign<D> for OrderedDecimal<D>
451where
452 D: Mul<Output = D> + Copy,
453{
454 fn mul_assign(&mut self, other: D) {
455 *self = *self * other;
456 }
457}
458
459impl<D> Div for OrderedDecimal<D>
460where
461 D: Div<Output = D>,
462{
463 type Output = Self;
464
465 fn div(self, other: OrderedDecimal<D>) -> Self {
466 OrderedDecimal(self.0 / other.0)
467 }
468}
469
470impl<D> Div<D> for OrderedDecimal<D>
471where
472 D: Div<Output = D>,
473{
474 type Output = Self;
475
476 fn div(self, other: D) -> Self {
477 OrderedDecimal(self.0 / other)
478 }
479}
480
481impl Div<OrderedDecimal<Decimal64>> for Decimal64 {
482 type Output = Self;
483
484 fn div(self, other: OrderedDecimal<Decimal64>) -> Self {
485 self / other.0
486 }
487}
488
489impl Div<OrderedDecimal<Decimal128>> for Decimal128 {
490 type Output = Self;
491
492 fn div(self, other: OrderedDecimal<Decimal128>) -> Self {
493 self / other.0
494 }
495}
496
497impl<D> DivAssign for OrderedDecimal<D>
498where
499 D: DivAssign,
500{
501 fn div_assign(&mut self, other: Self) {
502 self.0 /= other.0;
503 }
504}
505
506impl<D> DivAssign<D> for OrderedDecimal<D>
508where
509 D: Div<Output = D> + Copy,
510{
511 fn div_assign(&mut self, other: D) {
512 *self = *self / other;
513 }
514}
515
516impl<D> Rem for OrderedDecimal<D>
517where
518 D: Rem<Output = D>,
519{
520 type Output = Self;
521
522 fn rem(self, other: OrderedDecimal<D>) -> Self {
523 OrderedDecimal(self.0 % other.0)
524 }
525}
526
527impl<D> Rem<D> for OrderedDecimal<D>
528where
529 D: Rem<Output = D>,
530{
531 type Output = Self;
532
533 fn rem(self, other: D) -> Self {
534 OrderedDecimal(self.0 % other)
535 }
536}
537
538impl Rem<OrderedDecimal<Decimal64>> for Decimal64 {
539 type Output = Self;
540
541 fn rem(self, other: OrderedDecimal<Decimal64>) -> Self {
542 self % other.0
543 }
544}
545
546impl Rem<OrderedDecimal<Decimal128>> for Decimal128 {
547 type Output = Self;
548
549 fn rem(self, other: OrderedDecimal<Decimal128>) -> Self {
550 self % other.0
551 }
552}
553
554impl<D> RemAssign for OrderedDecimal<D>
555where
556 D: RemAssign,
557{
558 fn rem_assign(&mut self, other: Self) {
559 self.0 %= other.0;
560 }
561}
562
563impl<D> RemAssign<D> for OrderedDecimal<D>
565where
566 D: Rem<Output = D> + Copy,
567{
568 fn rem_assign(&mut self, other: D) {
569 *self = *self % other;
570 }
571}
572
573impl<D> Neg for OrderedDecimal<D>
574where
575 D: Neg<Output = D>,
576{
577 type Output = Self;
578
579 fn neg(self) -> Self {
580 OrderedDecimal(-self.0)
581 }
582}
583
584impl<D> Sum for OrderedDecimal<D>
585where
586 D: Sum,
587{
588 fn sum<I>(iter: I) -> Self
589 where
590 I: Iterator<Item = OrderedDecimal<D>>,
591 {
592 OrderedDecimal(iter.map(|v| v.0).sum())
593 }
594}
595
596impl<'a, D> Sum<&'a OrderedDecimal<D>> for OrderedDecimal<D>
597where
598 D: Sum<&'a D> + 'a,
599{
600 fn sum<I>(iter: I) -> Self
601 where
602 I: Iterator<Item = &'a OrderedDecimal<D>>,
603 {
604 OrderedDecimal(iter.map(|v| &v.0).sum())
605 }
606}
607
608impl<D> Product for OrderedDecimal<D>
609where
610 D: Product,
611{
612 fn product<I>(iter: I) -> Self
613 where
614 I: Iterator<Item = OrderedDecimal<D>>,
615 {
616 OrderedDecimal(iter.map(|v| v.0).product())
617 }
618}
619
620impl<'a, D> Product<&'a OrderedDecimal<D>> for OrderedDecimal<D>
621where
622 D: Product<&'a D> + 'a,
623{
624 fn product<I>(iter: I) -> Self
625 where
626 I: Iterator<Item = &'a OrderedDecimal<D>>,
627 {
628 OrderedDecimal(iter.map(|v| &v.0).product())
629 }
630}