smallint/
ord.rs

1use crate::smallint::{SmallIntType, SmallUintType};
2use crate::SmallInt;
3use crate::SmallUint;
4use std::cmp::Ordering;
5
6impl PartialEq for SmallUint {
7    fn eq(&self, other: &SmallUint) -> bool {
8        match (&self.0, &other.0) {
9            (SmallUintType::Inline(i), SmallUintType::Inline(j)) => i.eq(j),
10            (SmallUintType::Heap((r, s)), SmallUintType::Heap((i, j))) => match j.cmp(s) {
11                Ordering::Greater => false,
12                Ordering::Less => false,
13                Ordering::Equal => {
14                    let slice1 = unsafe { core::slice::from_raw_parts(r, *s) };
15                    let slice2 = unsafe { core::slice::from_raw_parts(i, *j) };
16                    for i in 0..*s {
17                        match slice1[s - 1 - i].cmp(&slice2[s - 1 - i]) {
18                            Ordering::Less => return false,
19                            Ordering::Greater => return false,
20                            _ => {}
21                        }
22                    }
23                    true
24                }
25            },
26            (_, _) => false,
27        }
28    }
29}
30
31impl Eq for SmallUint {}
32
33impl PartialOrd for SmallUint {
34    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
35        match (&self.0, &other.0) {
36            (SmallUintType::Inline(i), SmallUintType::Inline(j)) => Some(i.cmp(j)),
37            (SmallUintType::Inline(_), SmallUintType::Heap((_, _))) => Some(Ordering::Less),
38            (SmallUintType::Heap((_, _)), SmallUintType::Inline(_)) => Some(Ordering::Greater),
39            (SmallUintType::Heap((r, s)), SmallUintType::Heap((i, j))) => match j.cmp(s) {
40                Ordering::Greater => Some(Ordering::Less),
41                Ordering::Less => Some(Ordering::Greater),
42                Ordering::Equal => {
43                    let slice1 = unsafe { core::slice::from_raw_parts(r, *s) };
44                    let slice2 = unsafe { core::slice::from_raw_parts(i, *j) };
45                    for i in 0..*s {
46                        match slice1[s - 1 - i].cmp(&slice2[s - 1 - i]) {
47                            Ordering::Less => return Some(Ordering::Less),
48                            Ordering::Greater => return Some(Ordering::Greater),
49                            _ => {}
50                        }
51                    }
52                    Some(Ordering::Equal)
53                }
54            },
55        }
56    }
57}
58
59impl PartialEq for SmallInt {
60    fn eq(&self, other: &Self) -> bool {
61        match (&self.0, &other.0) {
62            (SmallIntType::Inline(i), SmallIntType::Inline(j)) => i.eq(j),
63            (SmallIntType::Heap((r, s)), SmallIntType::Heap((i, j))) => {
64                if s.signum() != j.signum() {
65                    return false;
66                }
67
68                match j.cmp(s) {
69                    Ordering::Greater => false,
70                    Ordering::Less => false,
71                    Ordering::Equal => {
72                        let us = usize::try_from(s.abs()).unwrap();
73                        let uj = usize::try_from(j.abs()).unwrap();
74                        let slice1 = unsafe { core::slice::from_raw_parts(r, us) };
75                        let slice2 = unsafe { core::slice::from_raw_parts(i, uj) };
76                        for i in 0..*s {
77                            match slice1[(s - 1 - i) as usize].cmp(&slice2[(s - 1 - i) as usize]) {
78                                Ordering::Less => return false,
79                                Ordering::Greater => return false,
80                                _ => {}
81                            }
82                        }
83                        true
84                    }
85                }
86            }
87            (_, _) => false,
88        }
89    }
90}
91
92impl Eq for SmallInt {}
93
94impl PartialOrd for SmallInt {
95    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
96        let a_sign;
97        match &self.0 {
98            SmallIntType::Inline(i) => a_sign = i.signum() as i8,
99            SmallIntType::Heap((_, s)) => a_sign = s.signum() as i8,
100        }
101
102        let b_sign;
103        match &other.0 {
104            SmallIntType::Inline(i) => b_sign = i.signum() as i8,
105            SmallIntType::Heap((_, s)) => b_sign = s.signum() as i8,
106        }
107
108        match (a_sign, b_sign) {
109            x if (x.0 >= 0 && x.1 < 0) => Some(Ordering::Greater),
110
111            x if (x.0 < 0 && x.1 >= 0) => Some(Ordering::Less),
112
113            x if (x.0 >= 0 && x.1 >= 0) => SmallUint::from_smallint_unsigned(self.clone())
114                .partial_cmp(&SmallUint::from_smallint_unsigned(other.clone())),
115
116            x if (x.0 < 0 && x.1 < 0) => SmallUint::from_smallint_unsigned(other.clone())
117                .partial_cmp(&SmallUint::from_smallint_unsigned(self.clone())),
118
119            (_, _) => None,
120        }
121    }
122}
123
124impl Ord for SmallInt {
125    fn cmp(&self, other: &Self) -> Ordering {
126        self.partial_cmp(other).expect("This should not happen.")
127    }
128}