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 _ => unreachable!("cmp_same_variant called with different variants"),
124 }
125 }
126
127 fn fuzzy_cmp(&self, other: &Self) -> Option<Ordering> {
128 use AnyValue::*;
129
130 if self.is_float() && other.is_float() {
131 self.cmp_float(other)
132 } else if self.is_int() && other.is_int() {
133 self.cmp_int(other)
134 } else if self.is_string() && other.is_string() {
135 self.cmp_str(other)
136 } else if self.is_int() && other.is_float() {
137 self.clone()
138 .cast(&other.dtype())
139 .and_then(|v| v.fuzzy_cmp(other))
140 } else if self.is_float() && other.is_int() {
141 self.clone()
142 .cast(&other.dtype())
143 .and_then(|v| v.fuzzy_cmp(other))
144 } else {
145 let res = match (self, other) {
146 (Null, Null) => Ordering::Equal,
147 (Bool(a), Bool(b)) => a.cmp(b),
148
149 (Vector(a), Vector(b)) => a.iter().cmp(b.iter()),
150 (Slice(a), Slice(b)) => a.iter().cmp(b.iter()),
151
152 _ => return None,
153 };
154
155 Some(res)
156 }
157 }
158
159 fn cmp_float(&self, other: &Self) -> Option<Ordering> {
160 use AnyValue::*;
161
162 match (self, other) {
163 (Float32(a), Float32(b)) => Some(a.total_cmp(b)),
164 (Float64(a), Float64(b)) => Some(a.total_cmp(b)),
165 (Float32(a), Float64(b)) => Some((*a as f64).total_cmp(b)),
166 (Float64(a), Float32(b)) => Some(a.total_cmp(&(*b as f64))),
167 _ => None,
168 }
169 }
170
171 fn cmp_str(&self, other: &Self) -> Option<Ordering> {
172 use AnyValue::*;
173
174 match (self, other) {
175 (Str(a), Str(b)) => Some(a.cmp(b)),
176 (StrOwned(a), StrOwned(b)) => Some(a.cmp(b)),
177 (Char(a), Char(b)) => Some(a.cmp(b)),
178
179 (Str(a), StrOwned(b)) => Some(a.cmp(&b.as_str())),
180 (StrOwned(a), Str(b)) => Some(a.as_str().cmp(b)),
181 _ => None,
182 }
183 }
184
185 fn cmp_int(&self, other: &Self) -> Option<Ordering> {
186 use AnyValue::*;
187
188 match (self, other) {
189 (Int8(a), Int8(b)) => Some(a.cmp(b)),
190 (Int16(a), Int16(b)) => Some(a.cmp(b)),
191 (Int32(a), Int32(b)) => Some(a.cmp(b)),
192 (Int64(a), Int64(b)) => Some(a.cmp(b)),
193 (Int128(a), Int128(b)) => Some(a.cmp(b)),
194
195 (UInt8(a), UInt8(b)) => Some(a.cmp(b)),
196 (UInt16(a), UInt16(b)) => Some(a.cmp(b)),
197 (UInt32(a), UInt32(b)) => Some(a.cmp(b)),
198 (UInt64(a), UInt64(b)) => Some(a.cmp(b)),
199 (UInt128(a), UInt128(b)) => Some(a.cmp(b)),
200
201 (Int8(a), Int16(b)) => Some((*a as i16).cmp(b)),
202 (Int8(a), Int32(b)) => Some((*a as i32).cmp(b)),
203 (Int8(a), Int64(b)) => Some((*a as i64).cmp(b)),
204 (Int8(a), Int128(b)) => Some((*a as i128).cmp(b)),
205 (Int8(a), UInt8(b)) => Some((*a as i16).cmp(&(*b as i16))),
206 (Int8(a), UInt16(b)) => Some((*a as i32).cmp(&(*b as i32))),
207 (Int8(a), UInt32(b)) => Some((*a as i64).cmp(&(*b as i64))),
208 (Int8(a), UInt64(b)) => Some((*a as i128).cmp(&(*b as i128))),
209
210 (Int16(a), Int8(b)) => Some(a.cmp(&(*b as i16))),
211 (Int16(a), Int32(b)) => Some((*a as i32).cmp(b)),
212 (Int16(a), Int64(b)) => Some((*a as i64).cmp(b)),
213 (Int16(a), Int128(b)) => Some((*a as i128).cmp(b)),
214 (Int16(a), UInt8(b)) => Some((*a as i32).cmp(&(*b as i32))),
215 (Int16(a), UInt16(b)) => Some((*a as i32).cmp(&(*b as i32))),
216 (Int16(a), UInt32(b)) => Some((*a as i64).cmp(&(*b as i64))),
217 (Int16(a), UInt64(b)) => Some((*a as i128).cmp(&(*b as i128))),
218
219 (Int32(a), Int8(b)) => Some(a.cmp(&(*b as i32))),
220 (Int32(a), Int16(b)) => Some(a.cmp(&(*b as i32))),
221 (Int32(a), Int64(b)) => Some((*a as i64).cmp(b)),
222 (Int32(a), Int128(b)) => Some((*a as i128).cmp(b)),
223 (Int32(a), UInt8(b)) => Some((*a as i64).cmp(&(*b as i64))),
224 (Int32(a), UInt16(b)) => Some((*a as i64).cmp(&(*b as i64))),
225 (Int32(a), UInt32(b)) => Some((*a as i64).cmp(&(*b as i64))),
226 (Int32(a), UInt64(b)) => Some((*a as i128).cmp(&(*b as i128))),
227
228 (Int64(a), Int8(b)) => Some(a.cmp(&(*b as i64))),
229 (Int64(a), Int16(b)) => Some(a.cmp(&(*b as i64))),
230 (Int64(a), Int32(b)) => Some(a.cmp(&(*b as i64))),
231 (Int64(a), Int128(b)) => Some((*a as i128).cmp(b)),
232 (Int64(a), UInt8(b)) => Some((*a as i128).cmp(&(*b as i128))),
233 (Int64(a), UInt16(b)) => Some((*a as i128).cmp(&(*b as i128))),
234 (Int64(a), UInt32(b)) => Some((*a as i128).cmp(&(*b as i128))),
235 (Int64(a), UInt64(b)) => Some((*a as i128).cmp(&(*b as i128))),
236
237 (UInt8(a), UInt16(b)) => Some((*a as u16).cmp(b)),
238 (UInt8(a), UInt32(b)) => Some((*a as u32).cmp(b)),
239 (UInt8(a), UInt64(b)) => Some((*a as u64).cmp(b)),
240 (UInt8(a), UInt128(b)) => Some((*a as u128).cmp(b)),
241 (UInt8(a), Int8(b)) => Some((*a as i16).cmp(&(*b as i16))),
242 (UInt8(a), Int16(b)) => Some((*a as i32).cmp(&(*b as i32))),
243 (UInt8(a), Int32(b)) => Some((*a as i64).cmp(&(*b as i64))),
244 (UInt8(a), Int64(b)) => Some((*a as i128).cmp(&(*b as i128))),
245
246 (UInt16(a), UInt8(b)) => Some(a.cmp(&(*b as u16))),
247 (UInt16(a), UInt32(b)) => Some((*a as u32).cmp(b)),
248 (UInt16(a), UInt64(b)) => Some((*a as u64).cmp(b)),
249 (UInt16(a), UInt128(b)) => Some((*a as u128).cmp(b)),
250 (UInt16(a), Int8(b)) => Some((*a as i32).cmp(&(*b as i32))),
251 (UInt16(a), Int16(b)) => Some((*a as i32).cmp(&(*b as i32))),
252 (UInt16(a), Int32(b)) => Some((*a as i64).cmp(&(*b as i64))),
253 (UInt16(a), Int64(b)) => Some((*a as i128).cmp(&(*b as i128))),
254
255 (UInt32(a), UInt8(b)) => Some(a.cmp(&(*b as u32))),
256 (UInt32(a), UInt16(b)) => Some(a.cmp(&(*b as u32))),
257 (UInt32(a), UInt64(b)) => Some((*a as u64).cmp(b)),
258 (UInt32(a), UInt128(b)) => Some((*a as u128).cmp(b)),
259 (UInt32(a), Int8(b)) => Some((*a as i64).cmp(&(*b as i64))),
260 (UInt32(a), Int16(b)) => Some((*a as i64).cmp(&(*b as i64))),
261 (UInt32(a), Int32(b)) => Some((*a as i64).cmp(&(*b as i64))),
262 (UInt32(a), Int64(b)) => Some((*a as i128).cmp(&(*b as i128))),
263
264 (UInt64(a), UInt8(b)) => Some(a.cmp(&(*b as u64))),
265 (UInt64(a), UInt16(b)) => Some(a.cmp(&(*b as u64))),
266 (UInt64(a), UInt32(b)) => Some(a.cmp(&(*b as u64))),
267 (UInt64(a), UInt128(b)) => Some((*a as u128).cmp(b)),
268 (UInt64(a), Int8(b)) => Some((*a as i128).cmp(&(*b as i128))),
269 (UInt64(a), Int16(b)) => Some((*a as i128).cmp(&(*b as i128))),
270 (UInt64(a), Int32(b)) => Some((*a as i128).cmp(&(*b as i128))),
271 (UInt64(a), Int64(b)) => Some((*a as i128).cmp(&(*b as i128))),
272 _ => None,
273 }
274 }
275}
276
277impl<'a> PartialOrd for AnyValue<'a> {
278 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
279 Some(self.cmp(other))
280 }
281}
282
283impl<'a> Ord for AnyValue<'a> {
284 fn cmp(&self, other: &Self) -> Ordering {
285 if let Some(like_cmp) = self.fuzzy_cmp(other) {
286 like_cmp
287 } else {
288 match self.variant_rank().cmp(&other.variant_rank()) {
289 Ordering::Equal => self.cmp_same_variant(other),
290 non_eq => non_eq,
291 }
292 }
293 }
294}