1use std::cmp::Ordering;
11
12use crate::parser::ast::{Operator, Value};
13
14#[must_use]
51pub fn apply_equal(left: &Value, right: &Value) -> bool {
52 compare_values(left, right) == Some(Ordering::Equal)
53}
54
55#[must_use]
92pub fn apply_not_equal(left: &Value, right: &Value) -> bool {
93 !apply_equal(left, right)
94}
95
96#[must_use]
132pub fn apply_bitwise_and(left: &Value, right: &Value) -> bool {
133 match (left, right) {
134 (Value::Uint(a), Value::Uint(b)) => (a & b) != 0,
136
137 #[allow(clippy::cast_sign_loss)]
139 (Value::Int(a), Value::Int(b)) => ((*a as u64) & (*b as u64)) != 0,
140
141 #[allow(clippy::cast_sign_loss)]
143 (Value::Uint(a), Value::Int(b)) => (a & (*b as u64)) != 0,
144 #[allow(clippy::cast_sign_loss)]
145 (Value::Int(a), Value::Uint(b)) => ((*a as u64) & b) != 0,
146
147 _ => false,
149 }
150}
151
152#[must_use]
171pub fn compare_values(left: &Value, right: &Value) -> Option<Ordering> {
172 match (left, right) {
173 (Value::Uint(a), Value::Uint(b)) => Some(a.cmp(b)),
174 (Value::Int(a), Value::Int(b)) => Some(a.cmp(b)),
175 (Value::Uint(a), Value::Int(b)) => Some(i128::from(*a).cmp(&i128::from(*b))),
176 (Value::Int(a), Value::Uint(b)) => Some(i128::from(*a).cmp(&i128::from(*b))),
177 (Value::String(a), Value::String(b)) => Some(a.cmp(b)),
178 (Value::Bytes(a), Value::Bytes(b)) => Some(a.cmp(b)),
179 _ => None,
180 }
181}
182
183#[must_use]
196pub fn apply_less_than(left: &Value, right: &Value) -> bool {
197 compare_values(left, right) == Some(Ordering::Less)
198}
199
200#[must_use]
213pub fn apply_greater_than(left: &Value, right: &Value) -> bool {
214 compare_values(left, right) == Some(Ordering::Greater)
215}
216
217#[must_use]
230pub fn apply_less_equal(left: &Value, right: &Value) -> bool {
231 matches!(
232 compare_values(left, right),
233 Some(Ordering::Less | Ordering::Equal)
234 )
235}
236
237#[must_use]
250pub fn apply_greater_equal(left: &Value, right: &Value) -> bool {
251 matches!(
252 compare_values(left, right),
253 Some(Ordering::Greater | Ordering::Equal)
254 )
255}
256
257#[must_use]
337pub fn apply_operator(operator: &Operator, left: &Value, right: &Value) -> bool {
338 match operator {
339 Operator::Equal => apply_equal(left, right),
340 Operator::NotEqual => apply_not_equal(left, right),
341 Operator::LessThan => apply_less_than(left, right),
342 Operator::GreaterThan => apply_greater_than(left, right),
343 Operator::LessEqual => apply_less_equal(left, right),
344 Operator::GreaterEqual => apply_greater_equal(left, right),
345 Operator::BitwiseAnd => apply_bitwise_and(left, right),
346 Operator::BitwiseAndMask(mask) => {
347 let masked_left = match left {
349 Value::Uint(val) => Value::Uint(val & mask),
350 Value::Int(val) => {
351 let i64_mask = i64::try_from(*mask)
353 .unwrap_or_else(|_| i64::from_ne_bytes(mask.to_ne_bytes()));
354 Value::Int(val & i64_mask)
355 }
356 _ => return false, };
358 apply_equal(&masked_left, right)
359 }
360 }
361}
362
363#[cfg(test)]
364mod tests {
365 use super::*;
366
367 #[test]
368 fn test_apply_equal_uint_same_value() {
369 let left = Value::Uint(42);
370 let right = Value::Uint(42);
371 assert!(apply_equal(&left, &right));
372 }
373
374 #[test]
375 fn test_apply_equal_uint_different_value() {
376 let left = Value::Uint(42);
377 let right = Value::Uint(24);
378 assert!(!apply_equal(&left, &right));
379 }
380
381 #[test]
382 fn test_apply_equal_uint_zero() {
383 let left = Value::Uint(0);
384 let right = Value::Uint(0);
385 assert!(apply_equal(&left, &right));
386 }
387
388 #[test]
389 fn test_apply_equal_uint_max_value() {
390 let left = Value::Uint(u64::MAX);
391 let right = Value::Uint(u64::MAX);
392 assert!(apply_equal(&left, &right));
393 }
394
395 #[test]
396 fn test_apply_equal_int_same_value() {
397 let left = Value::Int(42);
398 let right = Value::Int(42);
399 assert!(apply_equal(&left, &right));
400 }
401
402 #[test]
403 fn test_apply_equal_int_different_value() {
404 let left = Value::Int(42);
405 let right = Value::Int(-42);
406 assert!(!apply_equal(&left, &right));
407 }
408
409 #[test]
410 fn test_apply_equal_int_negative() {
411 let left = Value::Int(-100);
412 let right = Value::Int(-100);
413 assert!(apply_equal(&left, &right));
414 }
415
416 #[test]
417 fn test_apply_equal_int_zero() {
418 let left = Value::Int(0);
419 let right = Value::Int(0);
420 assert!(apply_equal(&left, &right));
421 }
422
423 #[test]
424 fn test_apply_equal_int_extreme_values() {
425 let left = Value::Int(i64::MAX);
426 let right = Value::Int(i64::MAX);
427 assert!(apply_equal(&left, &right));
428
429 let left = Value::Int(i64::MIN);
430 let right = Value::Int(i64::MIN);
431 assert!(apply_equal(&left, &right));
432 }
433
434 #[test]
435 fn test_apply_equal_bytes_same_value() {
436 let left = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
437 let right = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
438 assert!(apply_equal(&left, &right));
439 }
440
441 #[test]
442 fn test_apply_equal_bytes_different_value() {
443 let left = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
444 let right = Value::Bytes(vec![0x50, 0x4b, 0x03, 0x04]);
445 assert!(!apply_equal(&left, &right));
446 }
447
448 #[test]
449 fn test_apply_equal_bytes_empty() {
450 let left = Value::Bytes(vec![]);
451 let right = Value::Bytes(vec![]);
452 assert!(apply_equal(&left, &right));
453 }
454
455 #[test]
456 fn test_apply_equal_bytes_different_length() {
457 let left = Value::Bytes(vec![0x7f, 0x45]);
458 let right = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
459 assert!(!apply_equal(&left, &right));
460 }
461
462 #[test]
463 fn test_apply_equal_bytes_single_byte() {
464 let left = Value::Bytes(vec![0x7f]);
465 let right = Value::Bytes(vec![0x7f]);
466 assert!(apply_equal(&left, &right));
467
468 let left = Value::Bytes(vec![0x7f]);
469 let right = Value::Bytes(vec![0x45]);
470 assert!(!apply_equal(&left, &right));
471 }
472
473 #[test]
474 fn test_apply_equal_string_same_value() {
475 let left = Value::String("hello".to_string());
476 let right = Value::String("hello".to_string());
477 assert!(apply_equal(&left, &right));
478 }
479
480 #[test]
481 fn test_apply_equal_string_different_value() {
482 let left = Value::String("hello".to_string());
483 let right = Value::String("world".to_string());
484 assert!(!apply_equal(&left, &right));
485 }
486
487 #[test]
488 fn test_apply_equal_string_empty() {
489 let left = Value::String(String::new());
490 let right = Value::String(String::new());
491 assert!(apply_equal(&left, &right));
492 }
493
494 #[test]
495 fn test_apply_equal_string_case_sensitive() {
496 let left = Value::String("Hello".to_string());
497 let right = Value::String("hello".to_string());
498 assert!(!apply_equal(&left, &right));
499 }
500
501 #[test]
502 fn test_apply_equal_string_unicode() {
503 let left = Value::String("🦀 Rust".to_string());
504 let right = Value::String("🦀 Rust".to_string());
505 assert!(apply_equal(&left, &right));
506
507 let left = Value::String("🦀 Rust".to_string());
508 let right = Value::String("🐍 Python".to_string());
509 assert!(!apply_equal(&left, &right));
510 }
511
512 #[test]
513 fn test_apply_equal_string_whitespace() {
514 let left = Value::String("hello world".to_string());
515 let right = Value::String("hello world".to_string());
516 assert!(apply_equal(&left, &right));
517
518 let left = Value::String("hello world".to_string());
519 let right = Value::String("hello world".to_string()); assert!(!apply_equal(&left, &right));
521 }
522
523 #[test]
525 fn test_apply_equal_uint_vs_int() {
526 let left = Value::Uint(42);
528 let right = Value::Int(42);
529 assert!(apply_equal(&left, &right));
530
531 let left = Value::Uint(0);
532 let right = Value::Int(0);
533 assert!(apply_equal(&left, &right));
534
535 let left = Value::Uint(42);
537 let right = Value::Int(-42);
538 assert!(!apply_equal(&left, &right));
539
540 let left = Value::Uint(u64::MAX);
542 let right = Value::Int(-1);
543 assert!(!apply_equal(&left, &right));
544 }
545
546 #[test]
547 fn test_apply_equal_uint_vs_bytes() {
548 let left = Value::Uint(42);
549 let right = Value::Bytes(vec![42]);
550 assert!(!apply_equal(&left, &right));
551 }
552
553 #[test]
554 fn test_apply_equal_uint_vs_string() {
555 let left = Value::Uint(42);
556 let right = Value::String("42".to_string());
557 assert!(!apply_equal(&left, &right));
558 }
559
560 #[test]
561 fn test_apply_equal_int_vs_bytes() {
562 let left = Value::Int(-42);
563 let right = Value::Bytes(vec![214]); assert!(!apply_equal(&left, &right));
565 }
566
567 #[test]
568 fn test_apply_equal_int_vs_string() {
569 let left = Value::Int(-42);
570 let right = Value::String("-42".to_string());
571 assert!(!apply_equal(&left, &right));
572 }
573
574 #[test]
575 fn test_apply_equal_bytes_vs_string() {
576 let left = Value::Bytes(vec![104, 101, 108, 108, 111]); let right = Value::String("hello".to_string());
578 assert!(!apply_equal(&left, &right));
579 }
580
581 #[test]
582 fn test_apply_equal_all_cross_type_combinations() {
583 let values = [
584 Value::Uint(42),
585 Value::Int(42),
586 Value::Bytes(vec![42]),
587 Value::String("42".to_string()),
588 ];
589
590 for (i, left) in values.iter().enumerate() {
592 for (j, right) in values.iter().enumerate() {
593 if i != j {
594 let result = apply_equal(left, right);
595 if (i <= 1) && (j <= 1) {
597 assert!(
598 result,
599 "Integer cross-type comparison should be true: {left:?} vs {right:?}"
600 );
601 } else {
602 assert!(
603 !result,
604 "Non-integer cross-type comparison should be false: {left:?} vs {right:?}"
605 );
606 }
607 }
608 }
609 }
610 }
611
612 #[test]
613 fn test_apply_equal_reflexivity() {
614 let values = vec![
615 Value::Uint(42),
616 Value::Int(-42),
617 Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]),
618 Value::String("hello".to_string()),
619 ];
620
621 for value in values {
623 assert!(
624 apply_equal(&value, &value),
625 "Value should be equal to itself: {value:?}"
626 );
627 }
628 }
629
630 #[test]
631 fn test_apply_equal_symmetry() {
632 let test_cases = vec![
633 (Value::Uint(42), Value::Uint(42)),
634 (Value::Int(-100), Value::Int(-100)),
635 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![1, 2, 3])),
636 (
637 Value::String("test".to_string()),
638 Value::String("test".to_string()),
639 ),
640 ];
641
642 for (left, right) in test_cases {
644 let left_to_right = apply_equal(&left, &right);
645 let right_to_left = apply_equal(&right, &left);
646 assert_eq!(
647 left_to_right, right_to_left,
648 "Equality should be symmetric: {left:?} vs {right:?}"
649 );
650 }
651 }
652
653 #[test]
654 fn test_apply_equal_transitivity() {
655 let a = Value::Uint(123);
657 let b = Value::Uint(123);
658 let c = Value::Uint(123);
659
660 assert!(apply_equal(&a, &b));
661 assert!(apply_equal(&b, &c));
662 assert!(apply_equal(&a, &c));
663 }
664
665 #[test]
666 fn test_apply_equal_edge_cases() {
667 let max_unsigned = Value::Uint(u64::MAX);
669 let max_signed = Value::Int(i64::MAX);
670 let min_int = Value::Int(i64::MIN);
671
672 assert!(apply_equal(&max_unsigned, &max_unsigned));
673 assert!(apply_equal(&max_signed, &max_signed));
674 assert!(apply_equal(&min_int, &min_int));
675
676 assert!(!apply_equal(&max_unsigned, &Value::Int(-1)));
679 assert!(apply_equal(&Value::Uint(i64::MAX as u64), &max_signed));
681
682 let empty_bytes = Value::Bytes(vec![]);
684 let empty_string = Value::String(String::new());
685
686 assert!(apply_equal(&empty_bytes, &empty_bytes));
687 assert!(apply_equal(&empty_string, &empty_string));
688 assert!(!apply_equal(&empty_bytes, &empty_string));
689 }
690
691 #[test]
693 fn test_apply_not_equal_uint_same_value() {
694 let left = Value::Uint(42);
695 let right = Value::Uint(42);
696 assert!(!apply_not_equal(&left, &right));
697 }
698
699 #[test]
700 fn test_apply_not_equal_uint_different_value() {
701 let left = Value::Uint(42);
702 let right = Value::Uint(24);
703 assert!(apply_not_equal(&left, &right));
704 }
705
706 #[test]
707 fn test_apply_not_equal_uint_zero() {
708 let left = Value::Uint(0);
709 let right = Value::Uint(0);
710 assert!(!apply_not_equal(&left, &right));
711 }
712
713 #[test]
714 fn test_apply_not_equal_uint_max_value() {
715 let left = Value::Uint(u64::MAX);
716 let right = Value::Uint(u64::MAX);
717 assert!(!apply_not_equal(&left, &right));
718
719 let left = Value::Uint(u64::MAX);
720 let right = Value::Uint(0);
721 assert!(apply_not_equal(&left, &right));
722 }
723
724 #[test]
725 fn test_apply_not_equal_int_same_value() {
726 let left = Value::Int(42);
727 let right = Value::Int(42);
728 assert!(!apply_not_equal(&left, &right));
729 }
730
731 #[test]
732 fn test_apply_not_equal_int_different_value() {
733 let left = Value::Int(42);
734 let right = Value::Int(-42);
735 assert!(apply_not_equal(&left, &right));
736 }
737
738 #[test]
739 fn test_apply_not_equal_int_negative() {
740 let left = Value::Int(-100);
741 let right = Value::Int(-100);
742 assert!(!apply_not_equal(&left, &right));
743
744 let left = Value::Int(-100);
745 let right = Value::Int(100);
746 assert!(apply_not_equal(&left, &right));
747 }
748
749 #[test]
750 fn test_apply_not_equal_int_zero() {
751 let left = Value::Int(0);
752 let right = Value::Int(0);
753 assert!(!apply_not_equal(&left, &right));
754 }
755
756 #[test]
757 fn test_apply_not_equal_int_extreme_values() {
758 let left = Value::Int(i64::MAX);
759 let right = Value::Int(i64::MAX);
760 assert!(!apply_not_equal(&left, &right));
761
762 let left = Value::Int(i64::MIN);
763 let right = Value::Int(i64::MIN);
764 assert!(!apply_not_equal(&left, &right));
765
766 let left = Value::Int(i64::MAX);
767 let right = Value::Int(i64::MIN);
768 assert!(apply_not_equal(&left, &right));
769 }
770
771 #[test]
772 fn test_apply_not_equal_bytes_same_value() {
773 let left = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
774 let right = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
775 assert!(!apply_not_equal(&left, &right));
776 }
777
778 #[test]
779 fn test_apply_not_equal_bytes_different_value() {
780 let left = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
781 let right = Value::Bytes(vec![0x50, 0x4b, 0x03, 0x04]);
782 assert!(apply_not_equal(&left, &right));
783 }
784
785 #[test]
786 fn test_apply_not_equal_bytes_empty() {
787 let left = Value::Bytes(vec![]);
788 let right = Value::Bytes(vec![]);
789 assert!(!apply_not_equal(&left, &right));
790 }
791
792 #[test]
793 fn test_apply_not_equal_bytes_different_length() {
794 let left = Value::Bytes(vec![0x7f, 0x45]);
795 let right = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
796 assert!(apply_not_equal(&left, &right));
797 }
798
799 #[test]
800 fn test_apply_not_equal_bytes_single_byte() {
801 let left = Value::Bytes(vec![0x7f]);
802 let right = Value::Bytes(vec![0x7f]);
803 assert!(!apply_not_equal(&left, &right));
804
805 let left = Value::Bytes(vec![0x7f]);
806 let right = Value::Bytes(vec![0x45]);
807 assert!(apply_not_equal(&left, &right));
808 }
809
810 #[test]
811 fn test_apply_not_equal_string_same_value() {
812 let left = Value::String("hello".to_string());
813 let right = Value::String("hello".to_string());
814 assert!(!apply_not_equal(&left, &right));
815 }
816
817 #[test]
818 fn test_apply_not_equal_string_different_value() {
819 let left = Value::String("hello".to_string());
820 let right = Value::String("world".to_string());
821 assert!(apply_not_equal(&left, &right));
822 }
823
824 #[test]
825 fn test_apply_not_equal_string_empty() {
826 let left = Value::String(String::new());
827 let right = Value::String(String::new());
828 assert!(!apply_not_equal(&left, &right));
829 }
830
831 #[test]
832 fn test_apply_not_equal_string_case_sensitive() {
833 let left = Value::String("Hello".to_string());
834 let right = Value::String("hello".to_string());
835 assert!(apply_not_equal(&left, &right));
836 }
837
838 #[test]
839 fn test_apply_not_equal_string_unicode() {
840 let left = Value::String("🦀 Rust".to_string());
841 let right = Value::String("🦀 Rust".to_string());
842 assert!(!apply_not_equal(&left, &right));
843
844 let left = Value::String("🦀 Rust".to_string());
845 let right = Value::String("🐍 Python".to_string());
846 assert!(apply_not_equal(&left, &right));
847 }
848
849 #[test]
850 fn test_apply_not_equal_string_whitespace() {
851 let left = Value::String("hello world".to_string());
852 let right = Value::String("hello world".to_string());
853 assert!(!apply_not_equal(&left, &right));
854
855 let left = Value::String("hello world".to_string());
856 let right = Value::String("hello world".to_string()); assert!(apply_not_equal(&left, &right));
858 }
859
860 #[test]
862 fn test_apply_not_equal_uint_vs_int() {
863 let left = Value::Uint(42);
865 let right = Value::Int(42);
866 assert!(!apply_not_equal(&left, &right));
867
868 let left = Value::Uint(0);
869 let right = Value::Int(0);
870 assert!(!apply_not_equal(&left, &right));
871
872 let left = Value::Uint(42);
874 let right = Value::Int(-42);
875 assert!(apply_not_equal(&left, &right));
876 }
877
878 #[test]
879 fn test_apply_not_equal_uint_vs_bytes() {
880 let left = Value::Uint(42);
881 let right = Value::Bytes(vec![42]);
882 assert!(apply_not_equal(&left, &right));
883 }
884
885 #[test]
886 fn test_apply_not_equal_uint_vs_string() {
887 let left = Value::Uint(42);
888 let right = Value::String("42".to_string());
889 assert!(apply_not_equal(&left, &right));
890 }
891
892 #[test]
893 fn test_apply_not_equal_int_vs_bytes() {
894 let left = Value::Int(-42);
895 let right = Value::Bytes(vec![214]); assert!(apply_not_equal(&left, &right));
897 }
898
899 #[test]
900 fn test_apply_not_equal_int_vs_string() {
901 let left = Value::Int(-42);
902 let right = Value::String("-42".to_string());
903 assert!(apply_not_equal(&left, &right));
904 }
905
906 #[test]
907 fn test_apply_not_equal_bytes_vs_string() {
908 let left = Value::Bytes(vec![104, 101, 108, 108, 111]); let right = Value::String("hello".to_string());
910 assert!(apply_not_equal(&left, &right));
911 }
912
913 #[test]
914 fn test_apply_not_equal_all_cross_type_combinations() {
915 let values = [
916 Value::Uint(42),
917 Value::Int(42),
918 Value::Bytes(vec![42]),
919 Value::String("42".to_string()),
920 ];
921
922 for (i, left) in values.iter().enumerate() {
924 for (j, right) in values.iter().enumerate() {
925 if i != j {
926 let result = apply_not_equal(left, right);
927 if (i <= 1) && (j <= 1) {
929 assert!(
930 !result,
931 "Integer cross-type not_equal should be false: {left:?} vs {right:?}"
932 );
933 } else {
934 assert!(
935 result,
936 "Non-integer cross-type not_equal should be true: {left:?} vs {right:?}"
937 );
938 }
939 }
940 }
941 }
942 }
943
944 #[test]
945 fn test_apply_not_equal_consistency_with_equal() {
946 let test_cases = vec![
947 (Value::Uint(42), Value::Uint(42)),
948 (Value::Uint(42), Value::Uint(24)),
949 (Value::Int(-100), Value::Int(-100)),
950 (Value::Int(-100), Value::Int(100)),
951 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![1, 2, 3])),
952 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![3, 2, 1])),
953 (
954 Value::String("test".to_string()),
955 Value::String("test".to_string()),
956 ),
957 (
958 Value::String("test".to_string()),
959 Value::String("different".to_string()),
960 ),
961 (Value::Uint(42), Value::Int(42)),
963 (Value::Uint(42), Value::String("42".to_string())),
964 (Value::Bytes(vec![42]), Value::Uint(42)),
965 ];
966
967 for (left, right) in test_cases {
969 let equal_result = apply_equal(&left, &right);
970 let not_equal_result = apply_not_equal(&left, &right);
971 assert_eq!(
972 equal_result, !not_equal_result,
973 "apply_not_equal should be negation of apply_equal: {left:?} vs {right:?}"
974 );
975 }
976 }
977
978 #[test]
979 fn test_apply_not_equal_edge_cases() {
980 let max_unsigned = Value::Uint(u64::MAX);
982 let max_signed = Value::Int(i64::MAX);
983 let min_int = Value::Int(i64::MIN);
984
985 assert!(!apply_not_equal(&max_unsigned, &max_unsigned));
986 assert!(!apply_not_equal(&max_signed, &max_signed));
987 assert!(!apply_not_equal(&min_int, &min_int));
988
989 let empty_bytes = Value::Bytes(vec![]);
991 let empty_string = Value::String(String::new());
992
993 assert!(!apply_not_equal(&empty_bytes, &empty_bytes));
994 assert!(!apply_not_equal(&empty_string, &empty_string));
995 assert!(apply_not_equal(&empty_bytes, &empty_string));
996 }
997
998 #[test]
999 fn test_apply_not_equal_various_value_combinations() {
1000 let test_cases = vec![
1002 (Value::Uint(0), Value::Uint(1), true),
1004 (Value::Uint(100), Value::Uint(100), false),
1005 (Value::Uint(u64::MAX), Value::Uint(u64::MAX - 1), true),
1006 (Value::Int(0), Value::Int(-1), true),
1008 (Value::Int(-50), Value::Int(-50), false),
1009 (Value::Int(i64::MIN), Value::Int(i64::MAX), true),
1010 (Value::Bytes(vec![0]), Value::Bytes(vec![1]), true),
1012 (
1013 Value::Bytes(vec![255, 254]),
1014 Value::Bytes(vec![255, 254]),
1015 false,
1016 ),
1017 (Value::Bytes(vec![]), Value::Bytes(vec![0]), true),
1018 (
1020 Value::String("a".to_string()),
1021 Value::String("b".to_string()),
1022 true,
1023 ),
1024 (
1025 Value::String("same".to_string()),
1026 Value::String("same".to_string()),
1027 false,
1028 ),
1029 (
1030 Value::String(String::new()),
1031 Value::String("non-empty".to_string()),
1032 true,
1033 ),
1034 ];
1035
1036 for (left, right, expected) in test_cases {
1037 assert_eq!(
1038 apply_not_equal(&left, &right),
1039 expected,
1040 "apply_not_equal({left:?}, {right:?}) should be {expected}"
1041 );
1042 }
1043 }
1044
1045 #[test]
1047 fn test_apply_bitwise_and_uint_basic() {
1048 assert!(apply_bitwise_and(&Value::Uint(0x01), &Value::Uint(0x01))); assert!(!apply_bitwise_and(&Value::Uint(0x02), &Value::Uint(0x01))); assert!(apply_bitwise_and(&Value::Uint(0x03), &Value::Uint(0x01))); }
1053
1054 #[test]
1055 fn test_apply_bitwise_and_uint_multiple_bits() {
1056 assert!(apply_bitwise_and(&Value::Uint(0xFF), &Value::Uint(0x0F))); assert!(!apply_bitwise_and(&Value::Uint(0xF0), &Value::Uint(0x0F))); assert!(!apply_bitwise_and(&Value::Uint(0xAA), &Value::Uint(0x55))); assert!(apply_bitwise_and(&Value::Uint(0xAA), &Value::Uint(0xAA))); }
1062
1063 #[test]
1064 fn test_apply_bitwise_and_uint_edge_cases() {
1065 assert!(!apply_bitwise_and(&Value::Uint(0), &Value::Uint(0xFF))); assert!(!apply_bitwise_and(&Value::Uint(0xFF), &Value::Uint(0))); assert!(!apply_bitwise_and(&Value::Uint(0), &Value::Uint(0))); assert!(apply_bitwise_and(&Value::Uint(u64::MAX), &Value::Uint(1))); assert!(apply_bitwise_and(
1073 &Value::Uint(u64::MAX),
1074 &Value::Uint(u64::MAX)
1075 )); }
1077
1078 #[test]
1079 fn test_apply_bitwise_and_uint_specific_patterns() {
1080 assert!(apply_bitwise_and(
1082 &Value::Uint(0x7F45_4C46),
1083 &Value::Uint(0xFF00_0000)
1084 )); assert!(apply_bitwise_and(
1086 &Value::Uint(0x504B_0304),
1087 &Value::Uint(0xFFFF_0000)
1088 )); assert!(!apply_bitwise_and(
1090 &Value::Uint(0x1234_5678),
1091 &Value::Uint(0x0000_0001)
1092 )); }
1094
1095 #[test]
1096 fn test_apply_bitwise_and_int_basic() {
1097 assert!(apply_bitwise_and(&Value::Int(1), &Value::Int(1))); assert!(!apply_bitwise_and(&Value::Int(2), &Value::Int(1))); assert!(apply_bitwise_and(&Value::Int(3), &Value::Int(1))); }
1102
1103 #[test]
1104 fn test_apply_bitwise_and_int_negative() {
1105 assert!(apply_bitwise_and(&Value::Int(-1), &Value::Int(1))); assert!(apply_bitwise_and(&Value::Int(-2), &Value::Int(2))); assert!(!apply_bitwise_and(&Value::Int(-2), &Value::Int(1))); }
1110
1111 #[test]
1112 fn test_apply_bitwise_and_int_zero() {
1113 assert!(!apply_bitwise_and(&Value::Int(0), &Value::Int(0xFF))); assert!(!apply_bitwise_and(&Value::Int(0xFF), &Value::Int(0))); assert!(!apply_bitwise_and(&Value::Int(0), &Value::Int(0))); }
1118
1119 #[test]
1120 fn test_apply_bitwise_and_int_extreme_values() {
1121 assert!(apply_bitwise_and(&Value::Int(i64::MAX), &Value::Int(1))); assert!(apply_bitwise_and(
1124 &Value::Int(i64::MIN),
1125 &Value::Int(i64::MIN)
1126 )); assert!(apply_bitwise_and(&Value::Int(i64::MIN), &Value::Int(-1))); }
1129
1130 #[test]
1131 fn test_apply_bitwise_and_mixed_int_uint() {
1132 assert!(apply_bitwise_and(&Value::Uint(0xFF), &Value::Int(0x0F))); assert!(apply_bitwise_and(&Value::Int(0xFF), &Value::Uint(0x0F))); assert!(!apply_bitwise_and(&Value::Uint(0xF0), &Value::Int(0x0F))); assert!(!apply_bitwise_and(&Value::Int(0xF0), &Value::Uint(0x0F))); }
1138
1139 #[test]
1140 fn test_apply_bitwise_and_mixed_negative_uint() {
1141 assert!(apply_bitwise_and(&Value::Int(-1), &Value::Uint(1))); assert!(apply_bitwise_and(&Value::Uint(1), &Value::Int(-1))); assert!(!apply_bitwise_and(&Value::Int(-2), &Value::Uint(1))); assert!(!apply_bitwise_and(&Value::Uint(1), &Value::Int(-2))); }
1147
1148 #[test]
1149 fn test_apply_bitwise_and_non_integer_types() {
1150 assert!(!apply_bitwise_and(
1152 &Value::String("test".to_string()),
1153 &Value::Uint(0x01)
1154 ));
1155 assert!(!apply_bitwise_and(
1156 &Value::Uint(0x01),
1157 &Value::String("test".to_string())
1158 ));
1159 assert!(!apply_bitwise_and(
1160 &Value::Bytes(vec![1]),
1161 &Value::Uint(0x01)
1162 ));
1163 assert!(!apply_bitwise_and(
1164 &Value::Uint(0x01),
1165 &Value::Bytes(vec![1])
1166 ));
1167 assert!(!apply_bitwise_and(
1168 &Value::String("a".to_string()),
1169 &Value::String("b".to_string())
1170 ));
1171 assert!(!apply_bitwise_and(
1172 &Value::Bytes(vec![1]),
1173 &Value::Bytes(vec![1])
1174 ));
1175 }
1176
1177 #[test]
1178 fn test_apply_bitwise_and_all_non_integer_combinations() {
1179 let non_integer_values = [Value::String("test".to_string()), Value::Bytes(vec![42])];
1180
1181 let integer_values = [Value::Uint(42), Value::Int(42)];
1182
1183 for non_int in &non_integer_values {
1185 for int_val in &integer_values {
1186 assert!(
1187 !apply_bitwise_and(non_int, int_val),
1188 "Non-integer & integer should be false: {non_int:?} & {int_val:?}"
1189 );
1190 assert!(
1191 !apply_bitwise_and(int_val, non_int),
1192 "Integer & non-integer should be false: {int_val:?} & {non_int:?}"
1193 );
1194 }
1195 }
1196
1197 for left in &non_integer_values {
1199 for right in &non_integer_values {
1200 assert!(
1201 !apply_bitwise_and(left, right),
1202 "Non-integer & non-integer should be false: {left:?} & {right:?}"
1203 );
1204 }
1205 }
1206 }
1207
1208 #[test]
1209 fn test_apply_bitwise_and_bit_patterns() {
1210 let test_cases = vec![
1212 (0b0000_0001_u64, 0b0000_0001_u64, true), (0b0000_0010_u64, 0b0000_0001_u64, false), (0b0000_0011_u64, 0b0000_0001_u64, true), (0b1111_1111_u64, 0b0000_1111_u64, true), (0b1111_0000_u64, 0b0000_1111_u64, false), (0b1010_1010_u64, 0b0101_0101_u64, false), (0b1010_1010_u64, 0b1010_1010_u64, true), (0b1111_1111_u64, 0b0000_0000_u64, false), (0b0000_0000_u64, 0b1111_1111_u64, false), ];
1223
1224 for (value, mask, expected) in test_cases {
1225 assert_eq!(
1226 apply_bitwise_and(&Value::Uint(value), &Value::Uint(mask)),
1227 expected,
1228 "apply_bitwise_and(0b{value:08b}, 0b{mask:08b}) should be {expected}"
1229 );
1230 }
1231 }
1232
1233 #[test]
1234 fn test_apply_bitwise_and_magic_file_patterns() {
1235 let elf_magic = Value::Uint(0x7F45_4C46);
1239 let elf_mask = Value::Uint(0xFFFF_FFFF);
1240 assert!(apply_bitwise_and(&elf_magic, &elf_mask));
1241
1242 assert!(apply_bitwise_and(&elf_magic, &Value::Uint(0x7F00_0000))); assert!(apply_bitwise_and(&elf_magic, &Value::Uint(0x0045_0000))); assert!(apply_bitwise_and(&elf_magic, &Value::Uint(0x0000_4C00))); assert!(apply_bitwise_and(&elf_magic, &Value::Uint(0x0000_0046))); let zip_magic = Value::Uint(0x504B_0304);
1250 assert!(apply_bitwise_and(&zip_magic, &Value::Uint(0x504B_0000))); assert!(!apply_bitwise_and(&zip_magic, &Value::Uint(0x0000_0001))); let pdf_magic = Value::Uint(0x2550_4446); assert!(apply_bitwise_and(&pdf_magic, &Value::Uint(0xFF00_0000))); assert!(apply_bitwise_and(&pdf_magic, &Value::Uint(0x00FF_0000))); }
1258
1259 #[test]
1260 fn test_apply_bitwise_and_symmetry() {
1261 let test_cases = vec![
1263 (Value::Uint(0xFF), Value::Uint(0x0F)),
1264 (Value::Int(42), Value::Int(24)),
1265 (Value::Uint(0xAAAA), Value::Int(0x5555)),
1266 (Value::Int(-1), Value::Uint(1)),
1267 ];
1268
1269 for (left, right) in test_cases {
1270 let left_to_right = apply_bitwise_and(&left, &right);
1271 let right_to_left = apply_bitwise_and(&right, &left);
1272 assert_eq!(
1273 left_to_right, right_to_left,
1274 "Bitwise AND should be commutative: {left:?} & {right:?}"
1275 );
1276 }
1277 }
1278
1279 #[test]
1280 fn test_apply_bitwise_and_associativity_concept() {
1281 let value = Value::Uint(0b1111_0000);
1284 let mask1 = Value::Uint(0b1100_0000);
1285 let mask2 = Value::Uint(0b0011_0000);
1286 let combined_mask = Value::Uint(0b1111_0000);
1287
1288 assert!(apply_bitwise_and(&value, &mask1));
1290 assert!(apply_bitwise_and(&value, &mask2));
1291 assert!(apply_bitwise_and(&value, &combined_mask));
1292 }
1293
1294 #[test]
1296 fn test_apply_operator_equal() {
1297 assert!(apply_operator(
1299 &Operator::Equal,
1300 &Value::Uint(42),
1301 &Value::Uint(42)
1302 ));
1303 assert!(!apply_operator(
1304 &Operator::Equal,
1305 &Value::Uint(42),
1306 &Value::Uint(24)
1307 ));
1308
1309 assert!(apply_operator(
1311 &Operator::Equal,
1312 &Value::String("hello".to_string()),
1313 &Value::String("hello".to_string())
1314 ));
1315 assert!(!apply_operator(
1316 &Operator::Equal,
1317 &Value::String("hello".to_string()),
1318 &Value::String("world".to_string())
1319 ));
1320
1321 assert!(apply_operator(
1323 &Operator::Equal,
1324 &Value::Uint(42),
1325 &Value::Int(42)
1326 ));
1327 }
1328
1329 #[test]
1330 fn test_apply_operator_not_equal() {
1331 assert!(!apply_operator(
1333 &Operator::NotEqual,
1334 &Value::Uint(42),
1335 &Value::Uint(42)
1336 ));
1337 assert!(apply_operator(
1338 &Operator::NotEqual,
1339 &Value::Uint(42),
1340 &Value::Uint(24)
1341 ));
1342
1343 assert!(!apply_operator(
1345 &Operator::NotEqual,
1346 &Value::String("hello".to_string()),
1347 &Value::String("hello".to_string())
1348 ));
1349 assert!(apply_operator(
1350 &Operator::NotEqual,
1351 &Value::String("hello".to_string()),
1352 &Value::String("world".to_string())
1353 ));
1354
1355 assert!(!apply_operator(
1357 &Operator::NotEqual,
1358 &Value::Uint(42),
1359 &Value::Int(42)
1360 ));
1361 }
1362
1363 #[test]
1364 fn test_apply_operator_bitwise_and() {
1365 assert!(apply_operator(
1367 &Operator::BitwiseAnd,
1368 &Value::Uint(0xFF),
1369 &Value::Uint(0x0F)
1370 ));
1371 assert!(!apply_operator(
1372 &Operator::BitwiseAnd,
1373 &Value::Uint(0xF0),
1374 &Value::Uint(0x0F)
1375 ));
1376
1377 assert!(apply_operator(
1379 &Operator::BitwiseAnd,
1380 &Value::Int(-1),
1381 &Value::Int(1)
1382 ));
1383 assert!(!apply_operator(
1384 &Operator::BitwiseAnd,
1385 &Value::Int(-2),
1386 &Value::Int(1)
1387 ));
1388
1389 assert!(apply_operator(
1391 &Operator::BitwiseAnd,
1392 &Value::Uint(0xFF),
1393 &Value::Int(0x0F)
1394 ));
1395
1396 assert!(!apply_operator(
1398 &Operator::BitwiseAnd,
1399 &Value::String("test".to_string()),
1400 &Value::Uint(0x01)
1401 ));
1402 }
1403
1404 #[test]
1405 fn test_apply_operator_all_operators_with_same_values() {
1406 let test_cases = vec![
1407 (Value::Uint(42), Value::Uint(42)),
1409 (Value::Int(-100), Value::Int(-100)),
1410 (
1411 Value::String("test".to_string()),
1412 Value::String("test".to_string()),
1413 ),
1414 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![1, 2, 3])),
1415 ];
1416
1417 for (left, right) in test_cases {
1418 assert!(
1420 apply_operator(&Operator::Equal, &left, &right),
1421 "Equal should be true for same values: {left:?} == {right:?}"
1422 );
1423
1424 assert!(
1426 !apply_operator(&Operator::NotEqual, &left, &right),
1427 "NotEqual should be false for same values: {left:?} != {right:?}"
1428 );
1429
1430 let bitwise_result = apply_operator(&Operator::BitwiseAnd, &left, &right);
1432 match &left {
1433 Value::Uint(n) => {
1434 let expected = *n != 0;
1436 assert_eq!(
1437 bitwise_result, expected,
1438 "BitwiseAnd for Uint({n}) should be {expected}"
1439 );
1440 }
1441 Value::Int(n) => {
1442 let expected = *n != 0;
1444 assert_eq!(
1445 bitwise_result, expected,
1446 "BitwiseAnd for Int({n}) should be {expected}"
1447 );
1448 }
1449 _ => {
1450 assert!(
1452 !bitwise_result,
1453 "BitwiseAnd should be false for non-integer types: {left:?}"
1454 );
1455 }
1456 }
1457 }
1458 }
1459
1460 #[test]
1461 fn test_apply_operator_all_operators_with_different_values() {
1462 let test_cases = vec![
1463 (Value::Uint(42), Value::Uint(24)),
1465 (Value::Int(100), Value::Int(-100)),
1466 (
1467 Value::String("hello".to_string()),
1468 Value::String("world".to_string()),
1469 ),
1470 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![4, 5, 6])),
1471 (Value::Uint(42), Value::String("42".to_string())),
1473 (Value::Int(42), Value::Bytes(vec![42])),
1474 ];
1475
1476 for (left, right) in test_cases {
1477 assert!(
1479 !apply_operator(&Operator::Equal, &left, &right),
1480 "Equal should be false for different values: {left:?} == {right:?}"
1481 );
1482
1483 assert!(
1485 apply_operator(&Operator::NotEqual, &left, &right),
1486 "NotEqual should be true for different values: {left:?} != {right:?}"
1487 );
1488
1489 let bitwise_result = apply_operator(&Operator::BitwiseAnd, &left, &right);
1491 match (&left, &right) {
1492 (Value::Uint(a), Value::Uint(b)) => {
1493 let expected = (a & b) != 0;
1494 assert_eq!(
1495 bitwise_result, expected,
1496 "BitwiseAnd for Uint({a}) & Uint({b}) should be {expected}"
1497 );
1498 }
1499 (Value::Int(a), Value::Int(b)) => {
1500 #[allow(clippy::cast_sign_loss)]
1501 let expected = ((*a as u64) & (*b as u64)) != 0;
1502 assert_eq!(
1503 bitwise_result, expected,
1504 "BitwiseAnd for Int({a}) & Int({b}) should be {expected}"
1505 );
1506 }
1507 (Value::Uint(a), Value::Int(b)) | (Value::Int(b), Value::Uint(a)) => {
1508 #[allow(clippy::cast_sign_loss)]
1509 let expected = (a & (*b as u64)) != 0;
1510 assert_eq!(
1511 bitwise_result, expected,
1512 "BitwiseAnd for mixed Uint/Int should be {expected}"
1513 );
1514 }
1515 _ => {
1516 assert!(
1518 !bitwise_result,
1519 "BitwiseAnd should be false for non-integer types: {left:?} & {right:?}"
1520 );
1521 }
1522 }
1523 }
1524 }
1525
1526 #[test]
1527 fn test_apply_operator_consistency_with_individual_functions() {
1528 let test_cases = vec![
1529 (Value::Uint(42), Value::Uint(42)),
1530 (Value::Uint(42), Value::Uint(24)),
1531 (Value::Int(-100), Value::Int(-100)),
1532 (Value::Int(100), Value::Int(-100)),
1533 (
1534 Value::String("test".to_string()),
1535 Value::String("test".to_string()),
1536 ),
1537 (
1538 Value::String("hello".to_string()),
1539 Value::String("world".to_string()),
1540 ),
1541 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![1, 2, 3])),
1542 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![4, 5, 6])),
1543 (Value::Uint(42), Value::Int(42)),
1545 (Value::Uint(42), Value::String("42".to_string())),
1546 (Value::Int(42), Value::Bytes(vec![42])),
1547 ];
1548
1549 for (left, right) in test_cases {
1550 assert_eq!(
1552 apply_operator(&Operator::Equal, &left, &right),
1553 apply_equal(&left, &right),
1554 "apply_operator(Equal) should match apply_equal for {left:?}, {right:?}"
1555 );
1556
1557 assert_eq!(
1558 apply_operator(&Operator::NotEqual, &left, &right),
1559 apply_not_equal(&left, &right),
1560 "apply_operator(NotEqual) should match apply_not_equal for {left:?}, {right:?}"
1561 );
1562
1563 assert_eq!(
1564 apply_operator(&Operator::BitwiseAnd, &left, &right),
1565 apply_bitwise_and(&left, &right),
1566 "apply_operator(BitwiseAnd) should match apply_bitwise_and for {left:?}, {right:?}"
1567 );
1568 }
1569 }
1570
1571 #[test]
1572 fn test_apply_operator_magic_rule_scenarios() {
1573 let elf_magic = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
1577 let elf_expected = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
1578 assert!(apply_operator(&Operator::Equal, &elf_magic, &elf_expected));
1579 assert!(!apply_operator(
1580 &Operator::NotEqual,
1581 &elf_magic,
1582 &elf_expected
1583 ));
1584
1585 let zip_magic = Value::Uint(0x504B_0304);
1587 let zip_expected = Value::Uint(0x504B_0304);
1588 assert!(apply_operator(&Operator::Equal, &zip_magic, &zip_expected));
1589
1590 let flags = Value::Uint(0b1101_0110);
1592 let flag_mask = Value::Uint(0b0000_0010); assert!(apply_operator(&Operator::BitwiseAnd, &flags, &flag_mask));
1594
1595 let no_flag_mask = Value::Uint(0b0000_0001); assert!(!apply_operator(
1597 &Operator::BitwiseAnd,
1598 &flags,
1599 &no_flag_mask
1600 ));
1601
1602 let content = Value::String("#!/bin/bash".to_string());
1604 let shebang = Value::String("#!/bin/bash".to_string());
1605 assert!(apply_operator(&Operator::Equal, &content, &shebang));
1606
1607 let not_shebang = Value::String("#!/usr/bin/python".to_string());
1608 assert!(apply_operator(&Operator::NotEqual, &content, ¬_shebang));
1609
1610 let version = Value::Uint(2);
1612 let expected_version = Value::Uint(2);
1613 let old_version = Value::Uint(1);
1614 assert!(apply_operator(
1615 &Operator::Equal,
1616 &version,
1617 &expected_version
1618 ));
1619 assert!(apply_operator(&Operator::NotEqual, &version, &old_version));
1620 }
1621
1622 #[test]
1623 fn test_apply_operator_edge_cases() {
1624 let max_uint = Value::Uint(u64::MAX);
1626 let min_signed = Value::Int(i64::MIN);
1627 let max_signed = Value::Int(i64::MAX);
1628
1629 assert!(apply_operator(&Operator::Equal, &max_uint, &max_uint));
1631 assert!(apply_operator(&Operator::Equal, &min_signed, &min_signed));
1632 assert!(apply_operator(&Operator::Equal, &max_signed, &max_signed));
1633
1634 assert!(apply_operator(&Operator::NotEqual, &max_uint, &min_signed));
1636 assert!(apply_operator(
1637 &Operator::NotEqual,
1638 &max_signed,
1639 &min_signed
1640 ));
1641
1642 assert!(apply_operator(
1644 &Operator::BitwiseAnd,
1645 &max_uint,
1646 &Value::Uint(1)
1647 ));
1648 assert!(apply_operator(
1649 &Operator::BitwiseAnd,
1650 &min_signed,
1651 &min_signed
1652 ));
1653
1654 let empty_bytes = Value::Bytes(vec![]);
1656 let empty_string = Value::String(String::new());
1657 assert!(apply_operator(&Operator::Equal, &empty_bytes, &empty_bytes));
1658 assert!(apply_operator(
1659 &Operator::Equal,
1660 &empty_string,
1661 &empty_string
1662 ));
1663 assert!(apply_operator(
1664 &Operator::NotEqual,
1665 &empty_bytes,
1666 &empty_string
1667 ));
1668
1669 let zero_uint = Value::Uint(0);
1671 let zero_signed = Value::Int(0);
1672 assert!(!apply_operator(
1673 &Operator::BitwiseAnd,
1674 &zero_uint,
1675 &Value::Uint(0xFF)
1676 ));
1677 assert!(!apply_operator(
1678 &Operator::BitwiseAnd,
1679 &zero_signed,
1680 &Value::Int(0xFF)
1681 ));
1682 assert!(!apply_operator(
1683 &Operator::NotEqual,
1684 &zero_uint,
1685 &zero_signed
1686 )); }
1688
1689 #[test]
1690 fn test_apply_operator_all_combinations() {
1691 let operators = [
1692 Operator::Equal,
1693 Operator::NotEqual,
1694 Operator::LessThan,
1695 Operator::GreaterThan,
1696 Operator::LessEqual,
1697 Operator::GreaterEqual,
1698 Operator::BitwiseAnd,
1699 Operator::BitwiseAndMask(0xFF),
1700 ];
1701 let values = [
1702 Value::Uint(42),
1703 Value::Int(-42),
1704 Value::Bytes(vec![42]),
1705 Value::String("42".to_string()),
1706 ];
1707
1708 for operator in &operators {
1710 for left in &values {
1711 for right in &values {
1712 let result = apply_operator(operator, left, right);
1714
1715 let expected = match operator {
1717 Operator::Equal => apply_equal(left, right),
1718 Operator::NotEqual => apply_not_equal(left, right),
1719 Operator::LessThan => apply_less_than(left, right),
1720 Operator::GreaterThan => apply_greater_than(left, right),
1721 Operator::LessEqual => apply_less_equal(left, right),
1722 Operator::GreaterEqual => apply_greater_equal(left, right),
1723 Operator::BitwiseAnd => apply_bitwise_and(left, right),
1724 Operator::BitwiseAndMask(mask) => {
1725 let masked_left = match left {
1727 Value::Uint(val) => Value::Uint(val & mask),
1728 Value::Int(val) => {
1729 let i64_mask = if i64::try_from(*mask).is_ok() {
1730 i64::try_from(*mask).unwrap_or(0)
1731 } else {
1732 i64::from_ne_bytes(mask.to_ne_bytes())
1733 };
1734 Value::Int(val & i64_mask)
1735 }
1736 _ => return, };
1738 apply_equal(&masked_left, right)
1739 }
1740 };
1741
1742 assert_eq!(
1743 result, expected,
1744 "apply_operator({operator:?}, {left:?}, {right:?}) should match individual function"
1745 );
1746 }
1747 }
1748 }
1749 }
1750
1751 #[test]
1754 fn test_compare_values_ordering() {
1755 use std::cmp::Ordering::*;
1756
1757 assert_eq!(
1759 compare_values(&Value::Uint(5), &Value::Uint(10)),
1760 Some(Less)
1761 );
1762 assert_eq!(
1763 compare_values(&Value::Uint(10), &Value::Uint(10)),
1764 Some(Equal)
1765 );
1766 assert_eq!(
1767 compare_values(&Value::Uint(10), &Value::Uint(5)),
1768 Some(Greater)
1769 );
1770 assert_eq!(
1771 compare_values(&Value::Int(-10), &Value::Int(-5)),
1772 Some(Less)
1773 );
1774 assert_eq!(
1775 compare_values(&Value::Int(i64::MIN), &Value::Int(0)),
1776 Some(Less)
1777 );
1778
1779 assert_eq!(compare_values(&Value::Int(-1), &Value::Uint(0)), Some(Less));
1781 assert_eq!(
1782 compare_values(&Value::Uint(42), &Value::Int(42)),
1783 Some(Equal)
1784 );
1785 assert_eq!(
1786 compare_values(&Value::Uint(u64::MAX), &Value::Int(-1)),
1787 Some(Greater)
1788 );
1789
1790 assert_eq!(
1792 compare_values(&Value::String("abc".into()), &Value::String("abd".into())),
1793 Some(Less)
1794 );
1795 assert_eq!(
1796 compare_values(&Value::String("abc".into()), &Value::String("abc".into())),
1797 Some(Equal)
1798 );
1799
1800 assert_eq!(
1802 compare_values(&Value::Bytes(vec![1]), &Value::Bytes(vec![2])),
1803 Some(Less)
1804 );
1805 assert_eq!(
1806 compare_values(&Value::Bytes(vec![1]), &Value::Bytes(vec![1])),
1807 Some(Equal)
1808 );
1809 assert_eq!(
1810 compare_values(&Value::Bytes(vec![1]), &Value::Bytes(vec![1, 2])),
1811 Some(Less)
1812 );
1813 assert_eq!(
1814 compare_values(&Value::Bytes(vec![]), &Value::Bytes(vec![1])),
1815 Some(Less)
1816 );
1817
1818 assert_eq!(
1820 compare_values(&Value::Uint(1), &Value::String("1".into())),
1821 None
1822 );
1823 assert_eq!(compare_values(&Value::Int(1), &Value::Bytes(vec![1])), None);
1824 }
1825
1826 #[test]
1827 fn test_comparison_operators_consistency() {
1828 let pairs = vec![
1830 (Value::Uint(5), Value::Uint(10)),
1831 (Value::Uint(10), Value::Uint(10)),
1832 (Value::Uint(10), Value::Uint(5)),
1833 (Value::Int(-10), Value::Int(-5)),
1834 (Value::Int(-1), Value::Uint(0)),
1835 (Value::Uint(u64::MAX), Value::Int(-1)),
1836 (Value::String("abc".into()), Value::String("abd".into())),
1837 (Value::Bytes(vec![1, 2]), Value::Bytes(vec![1, 3])),
1838 (Value::Bytes(vec![1]), Value::Bytes(vec![1, 2])),
1839 (Value::Uint(1), Value::String("1".into())), ];
1841
1842 for (left, right) in &pairs {
1843 let ord = compare_values(left, right);
1844 assert_eq!(
1845 apply_less_than(left, right),
1846 ord == Some(Ordering::Less),
1847 "< for {left:?}, {right:?}"
1848 );
1849 assert_eq!(
1850 apply_greater_than(left, right),
1851 ord == Some(Ordering::Greater),
1852 "> for {left:?}, {right:?}"
1853 );
1854 assert_eq!(
1855 apply_less_equal(left, right),
1856 matches!(ord, Some(Ordering::Less | Ordering::Equal)),
1857 "<= for {left:?}, {right:?}"
1858 );
1859 assert_eq!(
1860 apply_greater_equal(left, right),
1861 matches!(ord, Some(Ordering::Greater | Ordering::Equal)),
1862 ">= for {left:?}, {right:?}"
1863 );
1864 }
1865 }
1866}