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}