Skip to main content

radiate_utils/datatype/
compare.rs

1use crate::AnyValue;
2use std::cmp::Ordering;
3
4impl<'a> AnyValue<'a> {
5    #[inline]
6    fn variant_rank(&self) -> u8 {
7        match self {
8            AnyValue::Null => 0,
9            AnyValue::Bool(_) => 1,
10
11            AnyValue::UInt8(_) => 2,
12            AnyValue::UInt16(_) => 3,
13            AnyValue::UInt32(_) => 4,
14            AnyValue::UInt64(_) => 5,
15            AnyValue::UInt128(_) => 6,
16
17            AnyValue::Int8(_) => 7,
18            AnyValue::Int16(_) => 8,
19            AnyValue::Int32(_) => 9,
20            AnyValue::Int64(_) => 10,
21            AnyValue::Int128(_) => 11,
22
23            AnyValue::Float32(_) => 12,
24            AnyValue::Float64(_) => 13,
25
26            AnyValue::Usize(_) => 14,
27
28            AnyValue::Duration(_) => 15,
29
30            AnyValue::Char(_) => 16,
31            AnyValue::Str(_) => 17,
32            AnyValue::StrOwned(_) => 18,
33
34            AnyValue::Slice(_) => 19,
35            AnyValue::Vector(_) => 20,
36
37            AnyValue::Dict(_) => 21,
38
39            AnyValue::Struct(_, _) => 22,
40        }
41    }
42
43    fn cmp_same_variant(&self, other: &Self) -> Ordering {
44        use AnyValue::*;
45
46        match (self, other) {
47            (Null, Null) => Ordering::Equal,
48            (Bool(a), Bool(b)) => a.cmp(b),
49
50            (UInt8(a), UInt8(b)) => a.cmp(b),
51            (UInt16(a), UInt16(b)) => a.cmp(b),
52            (UInt32(a), UInt32(b)) => a.cmp(b),
53            (UInt64(a), UInt64(b)) => a.cmp(b),
54            (UInt128(a), UInt128(b)) => a.cmp(b),
55
56            (Int8(a), Int8(b)) => a.cmp(b),
57            (Int16(a), Int16(b)) => a.cmp(b),
58            (Int32(a), Int32(b)) => a.cmp(b),
59            (Int64(a), Int64(b)) => a.cmp(b),
60            (Int128(a), Int128(b)) => a.cmp(b),
61
62            (Float32(a), Float32(b)) => a.total_cmp(b),
63            (Float64(a), Float64(b)) => a.total_cmp(b),
64
65            (Duration(a), Duration(b)) => a.cmp(b),
66
67            (Char(a), Char(b)) => a.cmp(b),
68            (Str(a), Str(b)) => a.cmp(b),
69            (StrOwned(a), StrOwned(b)) => a.cmp(b),
70
71            (Slice(a), Slice(b)) => a.iter().cmp(b.iter()),
72            (Vector(a), Vector(b)) => a.iter().cmp(b.iter()),
73
74            (Dict(a), Dict(b)) => {
75                let mut i = 0;
76                while i < a.len() && i < b.len() {
77                    let (fa, _, va) = &a[i];
78                    let (fb, _, vb) = &b[i];
79
80                    match fa.cmp(fb) {
81                        Ordering::Equal => {}
82                        non_eq => return non_eq,
83                    }
84
85                    match va.cmp(vb) {
86                        Ordering::Equal => {}
87                        non_eq => return non_eq,
88                    }
89
90                    i += 1;
91                }
92
93                a.len().cmp(&b.len())
94            }
95
96            (Struct(fa, va), Struct(fb, vb)) => {
97                match fa.cmp(fb) {
98                    Ordering::Equal => {}
99                    non_eq => return non_eq,
100                }
101
102                let mut i = 0;
103                while i < va.len() && i < vb.len() {
104                    let (name_a, _, va) = &va[i];
105                    let (name_b, _, vb) = &vb[i];
106
107                    match name_a.cmp(name_b) {
108                        Ordering::Equal => {}
109                        non_eq => return non_eq,
110                    }
111
112                    match va.cmp(vb) {
113                        Ordering::Equal => {}
114                        non_eq => return non_eq,
115                    }
116
117                    i += 1;
118                }
119
120                va.len().cmp(&vb.len())
121            }
122
123            (Usize(a), Usize(b)) => a.cmp(b),
124
125            _ => unreachable!(
126                "cmp_same_variant called with different variants: {:?} and {:?}",
127                self, other
128            ),
129        }
130    }
131
132    fn fuzzy_cmp(&self, other: &Self) -> Option<Ordering> {
133        use AnyValue::*;
134
135        if self.is_float() && other.is_float() {
136            self.cmp_float(other)
137        } else if self.is_int() && other.is_int() {
138            self.cmp_int(other)
139        } else if self.is_string() && other.is_string() {
140            self.cmp_str(other)
141        } else if self.is_int() && other.is_float() {
142            self.clone()
143                .cast(&other.dtype())
144                .and_then(|v| v.fuzzy_cmp(other))
145        } else if self.is_float() && other.is_int() {
146            self.clone()
147                .cast(&other.dtype())
148                .and_then(|v| v.fuzzy_cmp(other))
149        } else {
150            let res = match (self, other) {
151                (Null, Null) => Ordering::Equal,
152                (Bool(a), Bool(b)) => a.cmp(b),
153
154                (Vector(a), Vector(b)) => a.iter().cmp(b.iter()),
155                (Slice(a), Slice(b)) => a.iter().cmp(b.iter()),
156
157                _ => return None,
158            };
159
160            Some(res)
161        }
162    }
163
164    fn cmp_float(&self, other: &Self) -> Option<Ordering> {
165        use AnyValue::*;
166
167        match (self, other) {
168            (Float32(a), Float32(b)) => Some(a.total_cmp(b)),
169            (Float64(a), Float64(b)) => Some(a.total_cmp(b)),
170            (Float32(a), Float64(b)) => Some((*a as f64).total_cmp(b)),
171            (Float64(a), Float32(b)) => Some(a.total_cmp(&(*b as f64))),
172            _ => None,
173        }
174    }
175
176    fn cmp_str(&self, other: &Self) -> Option<Ordering> {
177        use AnyValue::*;
178
179        match (self, other) {
180            (Str(a), Str(b)) => Some(a.cmp(b)),
181            (StrOwned(a), StrOwned(b)) => Some(a.cmp(b)),
182            (Char(a), Char(b)) => Some(a.cmp(b)),
183
184            (Str(a), StrOwned(b)) => Some(a.cmp(&b.as_str())),
185            (StrOwned(a), Str(b)) => Some(a.as_str().cmp(b)),
186            _ => None,
187        }
188    }
189
190    fn cmp_int(&self, other: &Self) -> Option<Ordering> {
191        use AnyValue::*;
192
193        match (self, other) {
194            (Int8(a), Int8(b)) => Some(a.cmp(b)),
195            (Int16(a), Int16(b)) => Some(a.cmp(b)),
196            (Int32(a), Int32(b)) => Some(a.cmp(b)),
197            (Int64(a), Int64(b)) => Some(a.cmp(b)),
198            (Int128(a), Int128(b)) => Some(a.cmp(b)),
199
200            (UInt8(a), UInt8(b)) => Some(a.cmp(b)),
201            (UInt16(a), UInt16(b)) => Some(a.cmp(b)),
202            (UInt32(a), UInt32(b)) => Some(a.cmp(b)),
203            (UInt64(a), UInt64(b)) => Some(a.cmp(b)),
204            (UInt128(a), UInt128(b)) => Some(a.cmp(b)),
205
206            (Int8(a), Int16(b)) => Some((*a as i16).cmp(b)),
207            (Int8(a), Int32(b)) => Some((*a as i32).cmp(b)),
208            (Int8(a), Int64(b)) => Some((*a as i64).cmp(b)),
209            (Int8(a), Int128(b)) => Some((*a as i128).cmp(b)),
210            (Int8(a), UInt8(b)) => Some((*a as i16).cmp(&(*b as i16))),
211            (Int8(a), UInt16(b)) => Some((*a as i32).cmp(&(*b as i32))),
212            (Int8(a), UInt32(b)) => Some((*a as i64).cmp(&(*b as i64))),
213            (Int8(a), UInt64(b)) => Some((*a as i128).cmp(&(*b as i128))),
214
215            (Int16(a), Int8(b)) => Some(a.cmp(&(*b as i16))),
216            (Int16(a), Int32(b)) => Some((*a as i32).cmp(b)),
217            (Int16(a), Int64(b)) => Some((*a as i64).cmp(b)),
218            (Int16(a), Int128(b)) => Some((*a as i128).cmp(b)),
219            (Int16(a), UInt8(b)) => Some((*a as i32).cmp(&(*b as i32))),
220            (Int16(a), UInt16(b)) => Some((*a as i32).cmp(&(*b as i32))),
221            (Int16(a), UInt32(b)) => Some((*a as i64).cmp(&(*b as i64))),
222            (Int16(a), UInt64(b)) => Some((*a as i128).cmp(&(*b as i128))),
223
224            (Int32(a), Int8(b)) => Some(a.cmp(&(*b as i32))),
225            (Int32(a), Int16(b)) => Some(a.cmp(&(*b as i32))),
226            (Int32(a), Int64(b)) => Some((*a as i64).cmp(b)),
227            (Int32(a), Int128(b)) => Some((*a as i128).cmp(b)),
228            (Int32(a), UInt8(b)) => Some((*a as i64).cmp(&(*b as i64))),
229            (Int32(a), UInt16(b)) => Some((*a as i64).cmp(&(*b as i64))),
230            (Int32(a), UInt32(b)) => Some((*a as i64).cmp(&(*b as i64))),
231            (Int32(a), UInt64(b)) => Some((*a as i128).cmp(&(*b as i128))),
232
233            (Int64(a), Int8(b)) => Some(a.cmp(&(*b as i64))),
234            (Int64(a), Int16(b)) => Some(a.cmp(&(*b as i64))),
235            (Int64(a), Int32(b)) => Some(a.cmp(&(*b as i64))),
236            (Int64(a), Int128(b)) => Some((*a as i128).cmp(b)),
237            (Int64(a), UInt8(b)) => Some((*a as i128).cmp(&(*b as i128))),
238            (Int64(a), UInt16(b)) => Some((*a as i128).cmp(&(*b as i128))),
239            (Int64(a), UInt32(b)) => Some((*a as i128).cmp(&(*b as i128))),
240            (Int64(a), UInt64(b)) => Some((*a as i128).cmp(&(*b as i128))),
241
242            (UInt8(a), UInt16(b)) => Some((*a as u16).cmp(b)),
243            (UInt8(a), UInt32(b)) => Some((*a as u32).cmp(b)),
244            (UInt8(a), UInt64(b)) => Some((*a as u64).cmp(b)),
245            (UInt8(a), UInt128(b)) => Some((*a as u128).cmp(b)),
246            (UInt8(a), Int8(b)) => Some((*a as i16).cmp(&(*b as i16))),
247            (UInt8(a), Int16(b)) => Some((*a as i32).cmp(&(*b as i32))),
248            (UInt8(a), Int32(b)) => Some((*a as i64).cmp(&(*b as i64))),
249            (UInt8(a), Int64(b)) => Some((*a as i128).cmp(&(*b as i128))),
250
251            (UInt16(a), UInt8(b)) => Some(a.cmp(&(*b as u16))),
252            (UInt16(a), UInt32(b)) => Some((*a as u32).cmp(b)),
253            (UInt16(a), UInt64(b)) => Some((*a as u64).cmp(b)),
254            (UInt16(a), UInt128(b)) => Some((*a as u128).cmp(b)),
255            (UInt16(a), Int8(b)) => Some((*a as i32).cmp(&(*b as i32))),
256            (UInt16(a), Int16(b)) => Some((*a as i32).cmp(&(*b as i32))),
257            (UInt16(a), Int32(b)) => Some((*a as i64).cmp(&(*b as i64))),
258            (UInt16(a), Int64(b)) => Some((*a as i128).cmp(&(*b as i128))),
259
260            (UInt32(a), UInt8(b)) => Some(a.cmp(&(*b as u32))),
261            (UInt32(a), UInt16(b)) => Some(a.cmp(&(*b as u32))),
262            (UInt32(a), UInt64(b)) => Some((*a as u64).cmp(b)),
263            (UInt32(a), UInt128(b)) => Some((*a as u128).cmp(b)),
264            (UInt32(a), Int8(b)) => Some((*a as i64).cmp(&(*b as i64))),
265            (UInt32(a), Int16(b)) => Some((*a as i64).cmp(&(*b as i64))),
266            (UInt32(a), Int32(b)) => Some((*a as i64).cmp(&(*b as i64))),
267            (UInt32(a), Int64(b)) => Some((*a as i128).cmp(&(*b as i128))),
268
269            (UInt64(a), UInt8(b)) => Some(a.cmp(&(*b as u64))),
270            (UInt64(a), UInt16(b)) => Some(a.cmp(&(*b as u64))),
271            (UInt64(a), UInt32(b)) => Some(a.cmp(&(*b as u64))),
272            (UInt64(a), UInt128(b)) => Some((*a as u128).cmp(b)),
273            (UInt64(a), Int8(b)) => Some((*a as i128).cmp(&(*b as i128))),
274            (UInt64(a), Int16(b)) => Some((*a as i128).cmp(&(*b as i128))),
275            (UInt64(a), Int32(b)) => Some((*a as i128).cmp(&(*b as i128))),
276            (UInt64(a), Int64(b)) => Some((*a as i128).cmp(&(*b as i128))),
277            _ => None,
278        }
279    }
280}
281
282impl<'a> PartialOrd for AnyValue<'a> {
283    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
284        Some(self.cmp(other))
285    }
286}
287
288impl<'a> Ord for AnyValue<'a> {
289    fn cmp(&self, other: &Self) -> Ordering {
290        if let Some(like_cmp) = self.fuzzy_cmp(other) {
291            like_cmp
292        } else {
293            match self.variant_rank().cmp(&other.variant_rank()) {
294                Ordering::Equal => self.cmp_same_variant(other),
295                non_eq => non_eq,
296            }
297        }
298    }
299}