Skip to main content

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