1use crate::value::{
2 date_time::{DateTimeValue, DateValue, TimeValue},
3 geography::Geography,
4 interval::IntervalValue,
5 list::List,
6 null::NullType,
7 Value,
8};
9use std::{cmp::Ordering as CmpOrdering, collections::HashMap, hash::Hash};
10
11impl PartialEq for Value {
13 fn eq(&self, other: &Self) -> bool {
14 match (self, other) {
15 (Value::Empty, Value::Empty) => true,
16 (Value::Null(a), Value::Null(b)) => a == b,
17 (Value::Bool(a), Value::Bool(b)) => a == b,
18 (Value::SmallInt(a), Value::SmallInt(b)) => a == b,
19 (Value::Int(a), Value::Int(b)) => a == b,
20 (Value::BigInt(a), Value::BigInt(b)) => a == b,
21 (Value::Float(a), Value::Float(b)) => (a == b) || (a.is_nan() && b.is_nan()),
22 (Value::Double(a), Value::Double(b)) => (a == b) || (a.is_nan() && b.is_nan()),
23 (Value::Decimal128(a), Value::Decimal128(b)) => a == b,
24 (Value::String(a), Value::String(b)) => a == b,
25 (Value::FixedString(a), Value::FixedString(b)) => a == b,
26 (Value::Date(a), Value::Date(b)) => a == b,
27 (Value::Time(a), Value::Time(b)) => a == b,
28 (Value::DateTime(a), Value::DateTime(b)) => a == b,
29 (Value::Vertex(a), Value::Vertex(b)) => a == b,
30 (Value::Edge(a), Value::Edge(b)) => a == b,
31 (Value::EdgeHeader(a), Value::EdgeHeader(b)) => a == b,
32 (Value::Path(a), Value::Path(b)) => a == b,
33 (Value::List(a), Value::List(b)) => a == b,
34 (Value::Map(a), Value::Map(b)) => a == b,
35 (Value::Set(a), Value::Set(b)) => a == b,
36 (Value::Geography(a), Value::Geography(b)) => a == b,
37 (Value::Vector(a), Value::Vector(b)) => a == b,
38 (Value::DataSet(a), Value::DataSet(b)) => a == b,
39 (Value::Json(a), Value::Json(b)) => a == b,
40 (Value::JsonB(a), Value::JsonB(b)) => a == b,
41 (Value::Json(a), Value::JsonB(b)) => a.to_value().ok() == Some(b.as_value().clone()),
43 (Value::JsonB(a), Value::Json(b)) => Some(a.as_value().clone()) == b.to_value().ok(),
44 (Value::Blob(a), Value::Blob(b)) => a == b,
45 (Value::Uuid(a), Value::Uuid(b)) => a == b,
46 (Value::Interval(a), Value::Interval(b)) => a == b,
47 (Value::VertexId(a), Value::VertexId(b)) => a == b,
48 (Value::EdgeId(a), Value::EdgeId(b)) => a == b,
49 (Value::Struct(a), Value::Struct(b)) => a == b,
50 (Value::Array(a), Value::Array(b)) => a == b,
51
52 (Value::SmallInt(a), Value::Int(b)) => *a as i64 == *b as i64,
54 (Value::Int(a), Value::SmallInt(b)) => *a as i64 == *b as i64,
55 (Value::SmallInt(a), Value::BigInt(b)) => *a as i64 == *b,
56 (Value::BigInt(a), Value::SmallInt(b)) => *a == *b as i64,
57 (Value::Int(a), Value::BigInt(b)) => *a as i64 == *b,
58 (Value::BigInt(a), Value::Int(b)) => *a == *b as i64,
59
60 (Value::SmallInt(a), Value::Float(b)) => *a as f32 == *b,
62 (Value::Float(a), Value::SmallInt(b)) => *a == *b as f32,
63 (Value::Int(a), Value::Float(b)) => *a as f32 == *b,
64 (Value::Float(a), Value::Int(b)) => *a == *b as f32,
65 (Value::BigInt(a), Value::Float(b)) => *a as f32 == *b,
66 (Value::Float(a), Value::BigInt(b)) => *a == *b as f32,
67 (Value::SmallInt(a), Value::Double(b)) => *a as f64 == *b,
68 (Value::Double(a), Value::SmallInt(b)) => *a == *b as f64,
69 (Value::Int(a), Value::Double(b)) => *a as f64 == *b,
70 (Value::Double(a), Value::Int(b)) => *a == *b as f64,
71 (Value::BigInt(a), Value::Double(b)) => *a as f64 == *b,
72 (Value::Double(a), Value::BigInt(b)) => *a == *b as f64,
73 (Value::Float(a), Value::Double(b)) => *a as f64 == *b,
74 (Value::Double(a), Value::Float(b)) => *a == *b as f64,
75
76 _ => false,
77 }
78 }
79}
80
81impl Eq for Value {}
83
84impl PartialOrd for Value {
85 fn partial_cmp(&self, other: &Self) -> Option<CmpOrdering> {
86 Some(self.cmp(other))
87 }
88}
89
90impl Ord for Value {
91 fn cmp(&self, other: &Self) -> CmpOrdering {
92 match (self, other) {
93 (Value::Empty, Value::Empty) => CmpOrdering::Equal,
95 (Value::Null(a), Value::Null(b)) => Self::cmp_null(a, b),
96 (Value::Bool(a), Value::Bool(b)) => a.cmp(b),
97 (Value::SmallInt(a), Value::SmallInt(b)) => a.cmp(b),
98 (Value::Int(a), Value::Int(b)) => a.cmp(b),
99 (Value::BigInt(a), Value::BigInt(b)) => a.cmp(b),
100 (Value::Float(a), Value::Float(b)) => Self::cmp_f32(*a, *b),
101 (Value::Double(a), Value::Double(b)) => Self::cmp_f64(*a, *b),
102 (Value::Decimal128(a), Value::Decimal128(b)) => a.cmp(b),
103 (Value::Blob(a), Value::Blob(b)) => a.cmp(b),
104 (Value::String(a), Value::String(b)) => a.cmp(b),
105 (Value::FixedString(a), Value::FixedString(b)) => a.cmp(b),
106 (Value::Date(a), Value::Date(b)) => Self::cmp_date(a, b),
107 (Value::Time(a), Value::Time(b)) => Self::cmp_time(a, b),
108 (Value::DateTime(a), Value::DateTime(b)) => Self::cmp_datetime(a, b),
109 (Value::Vertex(a), Value::Vertex(b)) => a.cmp(b),
110 (Value::Edge(a), Value::Edge(b)) => a.cmp(b),
111 (Value::EdgeHeader(a), Value::EdgeHeader(b)) => a.cmp(b),
112 (Value::Path(a), Value::Path(b)) => a.cmp(b),
113 (Value::List(a), Value::List(b)) => Self::cmp_list(a, b),
114 (Value::Map(a), Value::Map(b)) => Self::cmp_map(a, b),
115 (Value::Set(a), Value::Set(b)) => Self::cmp_set(a, b),
116 (Value::Geography(a), Value::Geography(b)) => Self::cmp_geography(a, b),
117 (Value::Json(a), Value::Json(b)) => match (a.to_value(), b.to_value()) {
118 (Ok(a_val), Ok(b_val)) => Self::cmp_json_values(&a_val, &b_val),
119 _ => CmpOrdering::Equal,
120 },
121 (Value::JsonB(a), Value::JsonB(b)) => a.cmp(b),
122 (Value::Json(a), Value::JsonB(b)) => match a.to_value() {
124 Ok(a_val) => Self::cmp_json_values(&a_val, b.as_value()),
125 _ => CmpOrdering::Equal,
126 },
127 (Value::JsonB(a), Value::Json(b)) => match b.to_value() {
128 Ok(b_val) => Self::cmp_json_values(a.as_value(), &b_val),
129 _ => CmpOrdering::Equal,
130 },
131 (Value::Uuid(a), Value::Uuid(b)) => a.cmp(b),
132 (Value::Interval(a), Value::Interval(b)) => Self::cmp_interval(a, b),
133 (Value::Struct(a), Value::Struct(b)) => Self::cmp_struct(a, b),
134 (Value::Array(a), Value::Array(b)) => Self::cmp_array(a, b),
135
136 (Value::SmallInt(a), Value::Int(b)) => (*a as i64).cmp(&(*b as i64)),
138 (Value::Int(a), Value::SmallInt(b)) => (*a as i64).cmp(&(*b as i64)),
139 (Value::SmallInt(a), Value::BigInt(b)) => (*a as i64).cmp(b),
140 (Value::BigInt(a), Value::SmallInt(b)) => a.cmp(&(*b as i64)),
141 (Value::Int(a), Value::BigInt(b)) => (*a as i64).cmp(b),
142 (Value::BigInt(a), Value::Int(b)) => a.cmp(&(*b as i64)),
143
144 (Value::SmallInt(a), Value::Float(b)) => {
146 (*a as f32).partial_cmp(b).unwrap_or(CmpOrdering::Equal)
147 }
148 (Value::Float(a), Value::SmallInt(b)) => {
149 a.partial_cmp(&(*b as f32)).unwrap_or(CmpOrdering::Equal)
150 }
151 (Value::Int(a), Value::Float(b)) => {
152 (*a as f32).partial_cmp(b).unwrap_or(CmpOrdering::Equal)
153 }
154 (Value::Float(a), Value::Int(b)) => {
155 a.partial_cmp(&(*b as f32)).unwrap_or(CmpOrdering::Equal)
156 }
157 (Value::BigInt(a), Value::Float(b)) => {
158 (*a as f32).partial_cmp(b).unwrap_or(CmpOrdering::Equal)
159 }
160 (Value::Float(a), Value::BigInt(b)) => {
161 a.partial_cmp(&(*b as f32)).unwrap_or(CmpOrdering::Equal)
162 }
163 (Value::SmallInt(a), Value::Double(b)) => {
164 (*a as f64).partial_cmp(b).unwrap_or(CmpOrdering::Equal)
165 }
166 (Value::Double(a), Value::SmallInt(b)) => {
167 a.partial_cmp(&(*b as f64)).unwrap_or(CmpOrdering::Equal)
168 }
169 (Value::Int(a), Value::Double(b)) => {
170 (*a as f64).partial_cmp(b).unwrap_or(CmpOrdering::Equal)
171 }
172 (Value::Double(a), Value::Int(b)) => {
173 a.partial_cmp(&(*b as f64)).unwrap_or(CmpOrdering::Equal)
174 }
175 (Value::BigInt(a), Value::Double(b)) => {
176 (*a as f64).partial_cmp(b).unwrap_or(CmpOrdering::Equal)
177 }
178 (Value::Double(a), Value::BigInt(b)) => {
179 a.partial_cmp(&(*b as f64)).unwrap_or(CmpOrdering::Equal)
180 }
181 (Value::Float(a), Value::Double(b)) => {
182 (*a as f64).partial_cmp(b).unwrap_or(CmpOrdering::Equal)
183 }
184 (Value::Double(a), Value::Float(b)) => {
185 a.partial_cmp(&(*b as f64)).unwrap_or(CmpOrdering::Equal)
186 }
187
188 (a, b) => Self::cmp_by_type_priority(a, b),
190 }
191 }
192}
193
194impl Hash for Value {
196 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
197 match self {
198 Value::Empty => 0u8.hash(state),
199 Value::Null(n) => {
200 1u8.hash(state);
201 n.hash(state);
202 }
203 Value::Bool(b) => {
204 2u8.hash(state);
205 b.hash(state);
206 }
207 Value::SmallInt(i) => {
208 3u8.hash(state);
209 i.hash(state);
210 }
211 Value::Int(i) => {
212 4u8.hash(state);
213 i.hash(state);
214 }
215 Value::BigInt(i) => {
216 5u8.hash(state);
217 i.hash(state);
218 }
219 Value::Float(f) => {
220 6u8.hash(state);
221 if f.is_nan() {
223 0x7fc00000_u32.hash(state);
225 } else if *f == 0.0 {
226 0.0_f32.to_bits().hash(state);
228 } else {
229 f.to_bits().hash(state);
230 }
231 }
232 Value::Double(f) => {
233 7u8.hash(state);
234 if f.is_nan() {
236 0x7ff8000000000000_u64.hash(state);
238 } else if *f == 0.0 {
239 0.0_f64.to_bits().hash(state);
241 } else {
242 f.to_bits().hash(state);
243 }
244 }
245 Value::Decimal128(d) => {
246 8u8.hash(state);
247 d.hash(state);
248 }
249 Value::String(s) => {
250 9u8.hash(state);
251 s.hash(state);
252 }
253 Value::FixedString(data) => {
254 10u8.hash(state);
255 data.hash(state);
256 }
257 Value::Blob(b) => {
258 11u8.hash(state);
259 b.hash(state);
260 }
261 Value::Date(d) => {
262 12u8.hash(state);
263 d.hash(state);
264 }
265 Value::Time(t) => {
266 13u8.hash(state);
267 t.hash(state);
268 }
269 Value::DateTime(dt) => {
270 14u8.hash(state);
271 dt.hash(state);
272 }
273 Value::Vertex(v) => {
274 15u8.hash(state);
275 v.hash(state);
276 }
277 Value::Edge(e) => {
278 16u8.hash(state);
279 e.hash(state);
280 }
281 Value::EdgeHeader(h) => {
282 32u8.hash(state);
283 h.hash(state);
284 }
285 Value::Path(p) => {
286 17u8.hash(state);
287 p.hash(state);
288 }
289 Value::List(l) => {
290 18u8.hash(state);
291 l.hash(state);
292 }
293 Value::Map(m) => {
294 19u8.hash(state);
295 let mut pairs: Vec<_> = m.iter().collect();
297 pairs.sort();
298 pairs.hash(state);
299 }
300 Value::Set(s) => {
301 20u8.hash(state);
302 let mut values: Vec<_> = s.iter().collect();
304 values.sort();
305 values.hash(state);
306 }
307 Value::Geography(g) => {
308 21u8.hash(state);
309 g.hash(state);
310 }
311 Value::Json(j) => {
312 22u8.hash(state);
313 j.hash(state);
314 }
315 Value::JsonB(j) => {
316 23u8.hash(state);
317 j.hash(state);
318 }
319 Value::DataSet(ds) => {
320 24u8.hash(state);
321 ds.hash(state);
322 }
323 Value::Vector(v) => {
324 25u8.hash(state);
325 v.hash(state);
326 }
327 Value::Uuid(u) => {
328 26u8.hash(state);
329 u.hash(state);
330 }
331 Value::Interval(i) => {
332 27u8.hash(state);
333 i.hash(state);
334 }
335 Value::VertexId(vid) => {
336 28u8.hash(state);
337 vid.hash(state);
338 }
339 Value::EdgeId(eid) => {
340 29u8.hash(state);
341 eid.hash(state);
342 }
343 Value::Struct(s) => {
344 30u8.hash(state);
345 s.fields.hash(state);
346 }
347 Value::Array(a) => {
348 31u8.hash(state);
349 a.values.hash(state);
350 }
351 }
352 }
353}
354
355impl Value {
356 fn cmp_null(a: &NullType, b: &NullType) -> CmpOrdering {
358 match (a, b) {
359 (NullType::Null, NullType::Null) => CmpOrdering::Equal,
360 (NullType::NaN, NullType::NaN) => CmpOrdering::Equal,
361 (NullType::BadData, NullType::BadData) => CmpOrdering::Equal,
362 (NullType::BadType, NullType::BadType) => CmpOrdering::Equal,
363 _ => {
364 let priority_a = Self::null_type_priority(a);
365 let priority_b = Self::null_type_priority(b);
366 priority_a.cmp(&priority_b)
367 }
368 }
369 }
370
371 fn null_type_priority(typ: &NullType) -> u8 {
373 match typ {
374 NullType::Null => 0,
375 NullType::NaN => 1,
376 NullType::BadData => 2,
377 NullType::BadType => 2,
378 NullType::ErrOverflow => 3,
379 NullType::UnknownProp => 4,
380 NullType::DivByZero => 5,
381 NullType::OutOfRange => 6,
382 }
383 }
384
385 fn cmp_f32(a: f32, b: f32) -> CmpOrdering {
387 if a.is_nan() && b.is_nan() {
388 CmpOrdering::Equal
389 } else if a.is_nan() {
390 CmpOrdering::Less
391 } else if b.is_nan() {
392 CmpOrdering::Greater
393 } else {
394 a.partial_cmp(&b).unwrap_or(CmpOrdering::Equal)
395 }
396 }
397
398 fn cmp_f64(a: f64, b: f64) -> CmpOrdering {
400 if a.is_nan() && b.is_nan() {
401 CmpOrdering::Equal
402 } else if a.is_nan() {
403 CmpOrdering::Less
404 } else if b.is_nan() {
405 CmpOrdering::Greater
406 } else {
407 a.partial_cmp(&b).unwrap_or(CmpOrdering::Equal)
408 }
409 }
410
411 fn cmp_date(a: &DateValue, b: &DateValue) -> CmpOrdering {
413 match a.year.cmp(&b.year) {
414 CmpOrdering::Equal => match a.month.cmp(&b.month) {
415 CmpOrdering::Equal => a.day.cmp(&b.day),
416 ord => ord,
417 },
418 ord => ord,
419 }
420 }
421
422 fn cmp_time(a: &TimeValue, b: &TimeValue) -> CmpOrdering {
424 match a.hour.cmp(&b.hour) {
425 CmpOrdering::Equal => match a.minute.cmp(&b.minute) {
426 CmpOrdering::Equal => match a.sec.cmp(&b.sec) {
427 CmpOrdering::Equal => a.microsec.cmp(&b.microsec),
428 ord => ord,
429 },
430 ord => ord,
431 },
432 ord => ord,
433 }
434 }
435
436 fn cmp_datetime(a: &DateTimeValue, b: &DateTimeValue) -> CmpOrdering {
438 match a.year.cmp(&b.year) {
439 CmpOrdering::Equal => match a.month.cmp(&b.month) {
440 CmpOrdering::Equal => match a.day.cmp(&b.day) {
441 CmpOrdering::Equal => match a.hour.cmp(&b.hour) {
442 CmpOrdering::Equal => match a.minute.cmp(&b.minute) {
443 CmpOrdering::Equal => match a.sec.cmp(&b.sec) {
444 CmpOrdering::Equal => a.microsec.cmp(&b.microsec),
445 ord => ord,
446 },
447 ord => ord,
448 },
449 ord => ord,
450 },
451 ord => ord,
452 },
453 ord => ord,
454 },
455 ord => ord,
456 }
457 }
458
459 fn cmp_list(a: &List, b: &List) -> CmpOrdering {
461 a.values.len().cmp(&b.values.len()).then_with(|| {
462 a.values
463 .iter()
464 .zip(b.values.iter())
465 .fold(CmpOrdering::Equal, |acc, (a_val, b_val)| {
466 if acc == CmpOrdering::Equal {
467 a_val.cmp(b_val)
468 } else {
469 acc
470 }
471 })
472 })
473 }
474
475 fn cmp_map(a: &HashMap<Value, Value>, b: &HashMap<Value, Value>) -> CmpOrdering {
477 a.len().cmp(&b.len()).then_with(|| {
478 let mut a_pairs: Vec<_> = a.iter().collect();
479 let mut b_pairs: Vec<_> = b.iter().collect();
480 a_pairs.sort();
481 b_pairs.sort();
482 a_pairs.iter().zip(b_pairs.iter()).fold(
483 CmpOrdering::Equal,
484 |acc, ((a_k, a_v), (b_k, b_v))| {
485 if acc == CmpOrdering::Equal {
486 a_k.cmp(b_k).then_with(|| a_v.cmp(b_v))
487 } else {
488 acc
489 }
490 },
491 )
492 })
493 }
494
495 fn cmp_set(
497 a: &std::collections::HashSet<Value>,
498 b: &std::collections::HashSet<Value>,
499 ) -> CmpOrdering {
500 a.len().cmp(&b.len()).then_with(|| {
501 let mut a_values: Vec<_> = a.iter().collect();
502 let mut b_values: Vec<_> = b.iter().collect();
503 a_values.sort();
504 b_values.sort();
505 a_values
506 .iter()
507 .zip(b_values.iter())
508 .fold(CmpOrdering::Equal, |acc, (a_val, b_val)| {
509 if acc == CmpOrdering::Equal {
510 a_val.cmp(b_val)
511 } else {
512 acc
513 }
514 })
515 })
516 }
517
518 fn cmp_geography(a: &Geography, b: &Geography) -> CmpOrdering {
520 use crate::value::geography::Geography::*;
521
522 fn type_priority(geo: &Geography) -> u8 {
523 match geo {
524 Point(_) => 0,
525 LineString(_) => 1,
526 Polygon(_) => 2,
527 MultiPoint(_) => 3,
528 MultiLineString(_) => 4,
529 MultiPolygon(_) => 5,
530 }
531 }
532
533 fn cmp_points(
534 a: &[crate::value::geography::GeographyValue],
535 b: &[crate::value::geography::GeographyValue],
536 ) -> CmpOrdering {
537 a.len().cmp(&b.len()).then_with(|| {
538 for (pa, pb) in a.iter().zip(b.iter()) {
539 match pa.latitude.partial_cmp(&pb.latitude) {
540 Some(CmpOrdering::Equal) => match pa.longitude.partial_cmp(&pb.longitude) {
541 Some(CmpOrdering::Equal) => continue,
542 Some(ord) => return ord,
543 None => return CmpOrdering::Equal,
544 },
545 Some(ord) => return ord,
546 None => continue,
547 }
548 }
549 CmpOrdering::Equal
550 })
551 }
552
553 match (a, b) {
554 (Point(pa), Point(pb)) => match pa.latitude.partial_cmp(&pb.latitude) {
555 Some(CmpOrdering::Equal) => pa
556 .longitude
557 .partial_cmp(&pb.longitude)
558 .unwrap_or(CmpOrdering::Equal),
559 Some(ord) => ord,
560 None => CmpOrdering::Equal,
561 },
562 (LineString(la), LineString(lb)) => cmp_points(&la.points, &lb.points),
563 (Polygon(pa), Polygon(pb)) => cmp_points(&pa.exterior.points, &pb.exterior.points)
564 .then_with(|| pa.holes.len().cmp(&pb.holes.len())),
565 (MultiPoint(ma), MultiPoint(mb)) => cmp_points(&ma.points, &mb.points),
566 (MultiLineString(ma), MultiLineString(mb)) => ma
567 .linestrings
568 .len()
569 .cmp(&mb.linestrings.len())
570 .then_with(|| {
571 for (la, lb) in ma.linestrings.iter().zip(mb.linestrings.iter()) {
572 let ord = cmp_points(&la.points, &lb.points);
573 if ord != CmpOrdering::Equal {
574 return ord;
575 }
576 }
577 CmpOrdering::Equal
578 }),
579 (MultiPolygon(ma), MultiPolygon(mb)) => {
580 ma.polygons.len().cmp(&mb.polygons.len()).then_with(|| {
581 for (pa, pb) in ma.polygons.iter().zip(mb.polygons.iter()) {
582 let ord = cmp_points(&pa.exterior.points, &pb.exterior.points);
583 if ord != CmpOrdering::Equal {
584 return ord;
585 }
586 }
587 CmpOrdering::Equal
588 })
589 }
590 _ => type_priority(a).cmp(&type_priority(b)),
591 }
592 }
593
594 fn cmp_interval(a: &IntervalValue, b: &IntervalValue) -> CmpOrdering {
596 match a.months.cmp(&b.months) {
597 CmpOrdering::Equal => match a.days.cmp(&b.days) {
598 CmpOrdering::Equal => a.microseconds.cmp(&b.microseconds),
599 ord => ord,
600 },
601 ord => ord,
602 }
603 }
604
605 fn cmp_struct(a: &crate::value::StructValue, b: &crate::value::StructValue) -> CmpOrdering {
607 a.fields.len().cmp(&b.fields.len()).then_with(|| {
608 a.fields.iter().zip(b.fields.iter()).fold(
609 CmpOrdering::Equal,
610 |acc, ((a_k, a_v), (b_k, b_v))| {
611 if acc == CmpOrdering::Equal {
612 a_k.cmp(b_k).then_with(|| a_v.cmp(b_v))
613 } else {
614 acc
615 }
616 },
617 )
618 })
619 }
620
621 fn cmp_array(a: &crate::value::ArrayValue, b: &crate::value::ArrayValue) -> CmpOrdering {
623 a.values
624 .iter()
625 .zip(b.values.iter())
626 .fold(CmpOrdering::Equal, |acc, (a_val, b_val)| {
627 if acc == CmpOrdering::Equal {
628 a_val.cmp(b_val)
629 } else {
630 acc
631 }
632 })
633 .then_with(|| a.values.len().cmp(&b.values.len()))
634 }
635
636 fn cmp_json_values(a: &serde_json::Value, b: &serde_json::Value) -> CmpOrdering {
638 use serde_json::Value as JsonValue;
639 match (a, b) {
640 (JsonValue::Null, JsonValue::Null) => CmpOrdering::Equal,
641 (JsonValue::Bool(a), JsonValue::Bool(b)) => a.cmp(b),
642 (JsonValue::Number(a), JsonValue::Number(b)) => {
643 if let (Some(a_i64), Some(b_i64)) = (a.as_i64(), b.as_i64()) {
645 a_i64.cmp(&b_i64)
646 } else if let (Some(a_f64), Some(b_f64)) = (a.as_f64(), b.as_f64()) {
647 a_f64.partial_cmp(&b_f64).unwrap_or(CmpOrdering::Equal)
648 } else {
649 CmpOrdering::Equal
650 }
651 }
652 (JsonValue::String(a), JsonValue::String(b)) => a.cmp(b),
653 (JsonValue::Array(a), JsonValue::Array(b)) => a.len().cmp(&b.len()).then_with(|| {
654 a.iter()
655 .zip(b.iter())
656 .fold(CmpOrdering::Equal, |acc, (a_val, b_val)| {
657 if acc == CmpOrdering::Equal {
658 Self::cmp_json_values(a_val, b_val)
659 } else {
660 acc
661 }
662 })
663 }),
664 (JsonValue::Object(a), JsonValue::Object(b)) => a.len().cmp(&b.len()).then_with(|| {
665 let mut a_pairs: Vec<_> = a.iter().collect();
666 let mut b_pairs: Vec<_> = b.iter().collect();
667 a_pairs.sort_by_key(|&(k, _)| k);
668 b_pairs.sort_by_key(|&(k, _)| k);
669 a_pairs.iter().zip(b_pairs.iter()).fold(
670 CmpOrdering::Equal,
671 |acc, ((a_k, a_v), (b_k, b_v))| {
672 if acc == CmpOrdering::Equal {
673 a_k.cmp(b_k).then_with(|| Self::cmp_json_values(a_v, b_v))
674 } else {
675 acc
676 }
677 },
678 )
679 }),
680 (JsonValue::Null, _) => CmpOrdering::Less,
682 (_, JsonValue::Null) => CmpOrdering::Greater,
683 (JsonValue::Bool(_), _) => CmpOrdering::Less,
684 (_, JsonValue::Bool(_)) => CmpOrdering::Greater,
685 (JsonValue::Number(_), _) => CmpOrdering::Less,
686 (_, JsonValue::Number(_)) => CmpOrdering::Greater,
687 (JsonValue::String(_), _) => CmpOrdering::Less,
688 (_, JsonValue::String(_)) => CmpOrdering::Greater,
689 (JsonValue::Array(_), _) => CmpOrdering::Less,
690 (_, JsonValue::Array(_)) => CmpOrdering::Greater,
691 }
692 }
693
694 fn cmp_by_type_priority(a: &Value, b: &Value) -> CmpOrdering {
696 let priority_a = Self::type_priority(a);
697 let priority_b = Self::type_priority(b);
698 priority_a.cmp(&priority_b)
699 }
700
701 fn type_priority(value: &Value) -> u8 {
703 match value {
704 Value::Empty => 0,
705 Value::Null(_) => 1,
706 Value::Bool(_) => 2,
707 Value::SmallInt(_) => 3,
708 Value::Int(_) => 4,
709 Value::BigInt(_) => 5,
710 Value::Float(_) => 6,
711 Value::Double(_) => 7,
712 Value::Decimal128(_) => 8,
713 Value::Date(_) => 9,
714 Value::Time(_) => 10,
715 Value::DateTime(_) => 11,
716 Value::String(_) => 12,
717 Value::FixedString(_) => 13,
718 Value::Blob(_) => 14,
719 Value::Vertex(_) => 15,
720 Value::Edge(_) => 16,
721 Value::EdgeHeader(_) => 32,
722 Value::Path(_) => 17,
723 Value::List(_) => 18,
724 Value::Map(_) => 19,
725 Value::Set(_) => 20,
726 Value::Geography(_) => 21,
727 Value::Json(_) => 22,
728 Value::JsonB(_) => 23,
729 Value::DataSet(_) => 24,
730 Value::Vector(_) => 25,
731 Value::Uuid(_) => 26,
732 Value::Interval(_) => 27,
733 Value::VertexId(_) => 28,
734 Value::EdgeId(_) => 29,
735 Value::Struct(_) => 30,
736 Value::Array(_) => 31,
737 }
738 }
739}