1mod bitwise;
12mod comparison;
13mod equality;
14
15pub use bitwise::{
16 apply_bitwise_and, apply_bitwise_and_mask, apply_bitwise_and_mask_with_width,
17 apply_bitwise_not, apply_bitwise_not_with_width, apply_bitwise_xor,
18};
19pub use comparison::{
20 apply_greater_equal, apply_greater_than, apply_less_equal, apply_less_than, compare_values,
21};
22pub use equality::{apply_equal, apply_not_equal};
23
24use crate::error::EvaluationError;
25use crate::parser::ast::{Operator, Value, ValueTransform, ValueTransformOp};
26
27pub fn apply_value_transform(
60 value: &Value,
61 transform: ValueTransform,
62) -> Result<Value, EvaluationError> {
63 let signed_operand = transform.operand;
64 #[allow(clippy::cast_sign_loss)]
68 let bitwise_operand = signed_operand as u64;
69
70 match (value, transform.op) {
71 (Value::Uint(v), ValueTransformOp::Add) => {
72 let lhs = *v;
73 let result = if signed_operand >= 0 {
78 lhs.checked_add(signed_operand.unsigned_abs())
79 } else {
80 lhs.checked_sub(signed_operand.unsigned_abs())
81 };
82 result
83 .map(Value::Uint)
84 .ok_or_else(|| invalid_transform("Add", value, signed_operand))
85 }
86 (Value::Uint(v), ValueTransformOp::Sub) => {
87 let lhs = *v;
88 let result = if signed_operand >= 0 {
91 lhs.checked_sub(signed_operand.unsigned_abs())
92 } else {
93 lhs.checked_add(signed_operand.unsigned_abs())
94 };
95 result
96 .map(Value::Uint)
97 .ok_or_else(|| invalid_transform("Sub", value, signed_operand))
98 }
99 (Value::Uint(v), ValueTransformOp::Mul) => v
100 .checked_mul(bitwise_operand)
101 .map(Value::Uint)
102 .ok_or_else(|| invalid_transform("Mul", value, signed_operand)),
103 (Value::Uint(v), ValueTransformOp::Div) => {
104 if signed_operand == 0 {
105 return Err(invalid_transform("Div", value, signed_operand));
106 }
107 v.checked_div(bitwise_operand)
108 .map(Value::Uint)
109 .ok_or_else(|| invalid_transform("Div", value, signed_operand))
110 }
111 (Value::Uint(v), ValueTransformOp::Mod) => {
112 if signed_operand == 0 {
113 return Err(invalid_transform("Mod", value, signed_operand));
114 }
115 v.checked_rem(bitwise_operand)
116 .map(Value::Uint)
117 .ok_or_else(|| invalid_transform("Mod", value, signed_operand))
118 }
119 (Value::Uint(v), ValueTransformOp::BitAnd) => Ok(Value::Uint(v & bitwise_operand)),
120 (Value::Uint(v), ValueTransformOp::Or) => Ok(Value::Uint(v | bitwise_operand)),
121 (Value::Uint(v), ValueTransformOp::Xor) => Ok(Value::Uint(v ^ bitwise_operand)),
122
123 (Value::Int(v), ValueTransformOp::Add) => v
124 .checked_add(signed_operand)
125 .map(Value::Int)
126 .ok_or_else(|| invalid_transform("Add", value, signed_operand)),
127 (Value::Int(v), ValueTransformOp::Sub) => v
128 .checked_sub(signed_operand)
129 .map(Value::Int)
130 .ok_or_else(|| invalid_transform("Sub", value, signed_operand)),
131 (Value::Int(v), ValueTransformOp::Mul) => v
132 .checked_mul(signed_operand)
133 .map(Value::Int)
134 .ok_or_else(|| invalid_transform("Mul", value, signed_operand)),
135 (Value::Int(v), ValueTransformOp::Div) => {
136 if signed_operand == 0 {
137 return Err(invalid_transform("Div", value, signed_operand));
138 }
139 v.checked_div(signed_operand)
140 .map(Value::Int)
141 .ok_or_else(|| invalid_transform("Div", value, signed_operand))
142 }
143 (Value::Int(v), ValueTransformOp::Mod) => {
144 if signed_operand == 0 {
145 return Err(invalid_transform("Mod", value, signed_operand));
146 }
147 v.checked_rem(signed_operand)
148 .map(Value::Int)
149 .ok_or_else(|| invalid_transform("Mod", value, signed_operand))
150 }
151 (Value::Int(v), ValueTransformOp::BitAnd) => {
152 #[allow(clippy::cast_possible_wrap)]
153 let result = *v & (bitwise_operand as i64);
154 Ok(Value::Int(result))
155 }
156 (Value::Int(v), ValueTransformOp::Or) => {
157 #[allow(clippy::cast_possible_wrap)]
159 let result = *v | (bitwise_operand as i64);
160 Ok(Value::Int(result))
161 }
162 (Value::Int(v), ValueTransformOp::Xor) => {
163 #[allow(clippy::cast_possible_wrap)]
164 let result = *v ^ (bitwise_operand as i64);
165 Ok(Value::Int(result))
166 }
167
168 _ => Ok(value.clone()),
173 }
174}
175
176fn invalid_transform(op: &str, value: &Value, operand: i64) -> EvaluationError {
177 EvaluationError::InvalidValueTransform {
178 reason: format!("{op}({operand}) failed on {value:?} (overflow or div-by-zero)"),
179 }
180}
181
182#[must_use]
210pub fn apply_any_value(_left: &Value, _right: &Value) -> bool {
211 true
212}
213
214#[must_use]
307pub fn apply_operator(operator: &Operator, left: &Value, right: &Value) -> bool {
308 match operator {
309 Operator::Equal => apply_equal(left, right),
310 Operator::NotEqual => apply_not_equal(left, right),
311 Operator::LessThan => apply_less_than(left, right),
312 Operator::GreaterThan => apply_greater_than(left, right),
313 Operator::LessEqual => apply_less_equal(left, right),
314 Operator::GreaterEqual => apply_greater_equal(left, right),
315 Operator::BitwiseAnd => apply_bitwise_and(left, right),
316 Operator::BitwiseAndMask(mask) => apply_bitwise_and_mask(*mask, left, right),
317 Operator::BitwiseXor => apply_bitwise_xor(left, right),
318 Operator::BitwiseNot => apply_bitwise_not(left, right),
319 Operator::AnyValue => apply_any_value(left, right),
320 }
321}
322
323#[cfg(test)]
324mod tests {
325 use super::*;
326
327 fn t(op: ValueTransformOp, operand: i64) -> ValueTransform {
332 ValueTransform { op, operand }
333 }
334
335 #[test]
336 fn test_apply_value_transform_uint_arithmetic() {
337 assert_eq!(
339 apply_value_transform(&Value::Uint(100), t(ValueTransformOp::Add, 1)).unwrap(),
340 Value::Uint(101)
341 );
342 assert_eq!(
344 apply_value_transform(&Value::Uint(100), t(ValueTransformOp::Sub, 25)).unwrap(),
345 Value::Uint(75)
346 );
347 assert_eq!(
349 apply_value_transform(&Value::Uint(4), t(ValueTransformOp::Mul, 8)).unwrap(),
350 Value::Uint(32)
351 );
352 let sixteen_gib = 16u64 * 1024 * 1024 * 1024;
354 assert_eq!(
355 apply_value_transform(
356 &Value::Uint(sixteen_gib),
357 t(ValueTransformOp::Div, 1_073_741_824)
358 )
359 .unwrap(),
360 Value::Uint(16)
361 );
362 assert_eq!(
364 apply_value_transform(&Value::Uint(17), t(ValueTransformOp::Mod, 5)).unwrap(),
365 Value::Uint(2)
366 );
367 assert_eq!(
369 apply_value_transform(&Value::Uint(0xF0), t(ValueTransformOp::Or, 0x0F)).unwrap(),
370 Value::Uint(0xFF)
371 );
372 assert_eq!(
374 apply_value_transform(&Value::Uint(0xFF), t(ValueTransformOp::Xor, 0x0F)).unwrap(),
375 Value::Uint(0xF0)
376 );
377 }
378
379 #[test]
380 fn test_apply_value_transform_div_or_mod_by_zero_errors() {
381 let err = apply_value_transform(&Value::Uint(10), t(ValueTransformOp::Div, 0)).unwrap_err();
382 assert!(err.to_string().contains("Div"));
383 let err = apply_value_transform(&Value::Uint(10), t(ValueTransformOp::Mod, 0)).unwrap_err();
384 assert!(err.to_string().contains("Mod"));
385 }
386
387 #[test]
388 fn test_apply_value_transform_overflow_errors() {
389 let err =
390 apply_value_transform(&Value::Uint(u64::MAX), t(ValueTransformOp::Add, 1)).unwrap_err();
391 assert!(err.to_string().contains("Add"));
392 let err =
393 apply_value_transform(&Value::Uint(u64::MAX), t(ValueTransformOp::Mul, 2)).unwrap_err();
394 assert!(err.to_string().contains("Mul"));
395 }
396
397 #[test]
404 fn test_apply_value_transform_errors_use_invalid_value_transform_variant() {
405 let err = apply_value_transform(&Value::Uint(10), t(ValueTransformOp::Div, 0)).unwrap_err();
406 assert!(
407 matches!(err, EvaluationError::InvalidValueTransform { .. }),
408 "Div-by-zero must produce InvalidValueTransform, got {err:?}"
409 );
410
411 let err =
412 apply_value_transform(&Value::Uint(u64::MAX), t(ValueTransformOp::Mul, 2)).unwrap_err();
413 assert!(
414 matches!(err, EvaluationError::InvalidValueTransform { .. }),
415 "Overflow must produce InvalidValueTransform, got {err:?}"
416 );
417
418 let err =
419 apply_value_transform(&Value::Int(i64::MIN), t(ValueTransformOp::Sub, 1)).unwrap_err();
420 assert!(
421 matches!(err, EvaluationError::InvalidValueTransform { .. }),
422 "Int underflow must produce InvalidValueTransform, got {err:?}"
423 );
424 }
425
426 #[test]
427 fn test_apply_value_transform_int_arithmetic() {
428 assert_eq!(
429 apply_value_transform(&Value::Int(-5), t(ValueTransformOp::Add, 10)).unwrap(),
430 Value::Int(5)
431 );
432 assert_eq!(
433 apply_value_transform(&Value::Int(-3), t(ValueTransformOp::Mul, -2)).unwrap(),
434 Value::Int(6)
435 );
436 }
437
438 #[test]
439 fn test_apply_value_transform_non_numeric_passthrough() {
440 let s = Value::String("abc".to_string());
444 assert_eq!(
445 apply_value_transform(&s, t(ValueTransformOp::Add, 1)).unwrap(),
446 s
447 );
448 }
449
450 #[test]
451 fn test_apply_operator_equal() {
452 assert!(apply_operator(
454 &Operator::Equal,
455 &Value::Uint(42),
456 &Value::Uint(42)
457 ));
458 assert!(!apply_operator(
459 &Operator::Equal,
460 &Value::Uint(42),
461 &Value::Uint(24)
462 ));
463
464 assert!(apply_operator(
466 &Operator::Equal,
467 &Value::String("hello".to_string()),
468 &Value::String("hello".to_string())
469 ));
470 assert!(!apply_operator(
471 &Operator::Equal,
472 &Value::String("hello".to_string()),
473 &Value::String("world".to_string())
474 ));
475
476 assert!(apply_operator(
478 &Operator::Equal,
479 &Value::Uint(42),
480 &Value::Int(42)
481 ));
482 }
483
484 #[test]
485 fn test_apply_operator_not_equal() {
486 assert!(!apply_operator(
488 &Operator::NotEqual,
489 &Value::Uint(42),
490 &Value::Uint(42)
491 ));
492 assert!(apply_operator(
493 &Operator::NotEqual,
494 &Value::Uint(42),
495 &Value::Uint(24)
496 ));
497
498 assert!(!apply_operator(
500 &Operator::NotEqual,
501 &Value::String("hello".to_string()),
502 &Value::String("hello".to_string())
503 ));
504 assert!(apply_operator(
505 &Operator::NotEqual,
506 &Value::String("hello".to_string()),
507 &Value::String("world".to_string())
508 ));
509
510 assert!(!apply_operator(
512 &Operator::NotEqual,
513 &Value::Uint(42),
514 &Value::Int(42)
515 ));
516 }
517
518 #[test]
519 fn test_apply_operator_bitwise_and() {
520 assert!(apply_operator(
522 &Operator::BitwiseAnd,
523 &Value::Uint(0xFF),
524 &Value::Uint(0x0F)
525 ));
526 assert!(!apply_operator(
527 &Operator::BitwiseAnd,
528 &Value::Uint(0xF0),
529 &Value::Uint(0x0F)
530 ));
531
532 assert!(apply_operator(
534 &Operator::BitwiseAnd,
535 &Value::Int(-1),
536 &Value::Int(1)
537 ));
538 assert!(!apply_operator(
539 &Operator::BitwiseAnd,
540 &Value::Int(-2),
541 &Value::Int(1)
542 ));
543
544 assert!(apply_operator(
546 &Operator::BitwiseAnd,
547 &Value::Uint(0xFF),
548 &Value::Int(0x0F)
549 ));
550
551 assert!(!apply_operator(
553 &Operator::BitwiseAnd,
554 &Value::String("test".to_string()),
555 &Value::Uint(0x01)
556 ));
557 }
558
559 #[test]
560 fn test_apply_operator_all_operators_with_same_values() {
561 let test_cases = vec![
562 (Value::Uint(42), Value::Uint(42)),
564 (Value::Int(-100), Value::Int(-100)),
565 (
566 Value::String("test".to_string()),
567 Value::String("test".to_string()),
568 ),
569 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![1, 2, 3])),
570 ];
571
572 for (left, right) in test_cases {
573 assert!(
575 apply_operator(&Operator::Equal, &left, &right),
576 "Equal should be true for same values: {left:?} == {right:?}"
577 );
578
579 assert!(
581 !apply_operator(&Operator::NotEqual, &left, &right),
582 "NotEqual should be false for same values: {left:?} != {right:?}"
583 );
584
585 let bitwise_result = apply_operator(&Operator::BitwiseAnd, &left, &right);
587 match &left {
588 Value::Uint(n) => {
589 let expected = *n != 0;
591 assert_eq!(
592 bitwise_result, expected,
593 "BitwiseAnd for Uint({n}) should be {expected}"
594 );
595 }
596 Value::Int(n) => {
597 let expected = *n != 0;
599 assert_eq!(
600 bitwise_result, expected,
601 "BitwiseAnd for Int({n}) should be {expected}"
602 );
603 }
604 _ => {
605 assert!(
607 !bitwise_result,
608 "BitwiseAnd should be false for non-integer types: {left:?}"
609 );
610 }
611 }
612 }
613 }
614
615 #[test]
616 fn test_apply_operator_all_operators_with_different_values() {
617 let test_cases = vec![
618 (Value::Uint(42), Value::Uint(24)),
620 (Value::Int(100), Value::Int(-100)),
621 (
622 Value::String("hello".to_string()),
623 Value::String("world".to_string()),
624 ),
625 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![4, 5, 6])),
626 (Value::Uint(42), Value::String("42".to_string())),
628 (Value::Int(42), Value::Bytes(vec![42])),
629 ];
630
631 for (left, right) in test_cases {
632 assert!(
634 !apply_operator(&Operator::Equal, &left, &right),
635 "Equal should be false for different values: {left:?} == {right:?}"
636 );
637
638 assert!(
640 apply_operator(&Operator::NotEqual, &left, &right),
641 "NotEqual should be true for different values: {left:?} != {right:?}"
642 );
643
644 let bitwise_result = apply_operator(&Operator::BitwiseAnd, &left, &right);
649 match (&left, &right) {
650 (Value::Uint(a), Value::Uint(b)) => {
651 let expected = (a & b) == *b;
652 assert_eq!(
653 bitwise_result, expected,
654 "BitwiseAnd for Uint({a}) & Uint({b}) should be {expected}"
655 );
656 }
657 (Value::Int(a), Value::Int(b)) => {
658 #[allow(clippy::cast_sign_loss)]
659 let expected = {
660 let (a, b) = (*a as u64, *b as u64);
661 (a & b) == b
662 };
663 assert_eq!(
664 bitwise_result, expected,
665 "BitwiseAnd for Int({a}) & Int({b}) should be {expected}"
666 );
667 }
668 (Value::Uint(a), Value::Int(b)) => {
669 #[allow(clippy::cast_sign_loss)]
670 let b = *b as u64;
671 let expected = (a & b) == b;
672 assert_eq!(
673 bitwise_result, expected,
674 "BitwiseAnd for mixed Uint/Int should be {expected}"
675 );
676 }
677 (Value::Int(a), Value::Uint(b)) => {
678 #[allow(clippy::cast_sign_loss)]
679 let a = *a as u64;
680 let expected = (a & b) == *b;
681 assert_eq!(
682 bitwise_result, expected,
683 "BitwiseAnd for mixed Int/Uint should be {expected}"
684 );
685 }
686 _ => {
687 assert!(
689 !bitwise_result,
690 "BitwiseAnd should be false for non-integer types: {left:?} & {right:?}"
691 );
692 }
693 }
694 }
695 }
696
697 #[test]
698 fn test_apply_operator_consistency_with_individual_functions() {
699 let test_cases = vec![
700 (Value::Uint(42), Value::Uint(42)),
701 (Value::Uint(42), Value::Uint(24)),
702 (Value::Int(-100), Value::Int(-100)),
703 (Value::Int(100), Value::Int(-100)),
704 (
705 Value::String("test".to_string()),
706 Value::String("test".to_string()),
707 ),
708 (
709 Value::String("hello".to_string()),
710 Value::String("world".to_string()),
711 ),
712 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![1, 2, 3])),
713 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![4, 5, 6])),
714 (Value::Uint(42), Value::Int(42)),
716 (Value::Uint(42), Value::String("42".to_string())),
717 (Value::Int(42), Value::Bytes(vec![42])),
718 ];
719
720 for (left, right) in test_cases {
721 assert_eq!(
723 apply_operator(&Operator::Equal, &left, &right),
724 apply_equal(&left, &right),
725 "apply_operator(Equal) should match apply_equal for {left:?}, {right:?}"
726 );
727
728 assert_eq!(
729 apply_operator(&Operator::NotEqual, &left, &right),
730 apply_not_equal(&left, &right),
731 "apply_operator(NotEqual) should match apply_not_equal for {left:?}, {right:?}"
732 );
733
734 assert_eq!(
735 apply_operator(&Operator::BitwiseAnd, &left, &right),
736 apply_bitwise_and(&left, &right),
737 "apply_operator(BitwiseAnd) should match apply_bitwise_and for {left:?}, {right:?}"
738 );
739
740 assert_eq!(
741 apply_operator(&Operator::BitwiseXor, &left, &right),
742 apply_bitwise_xor(&left, &right),
743 "apply_operator(BitwiseXor) should match apply_bitwise_xor for {left:?}, {right:?}"
744 );
745
746 assert_eq!(
747 apply_operator(&Operator::BitwiseNot, &left, &right),
748 apply_bitwise_not(&left, &right),
749 "apply_operator(BitwiseNot) should match apply_bitwise_not for {left:?}, {right:?}"
750 );
751
752 assert!(
753 apply_operator(&Operator::AnyValue, &left, &right),
754 "apply_operator(AnyValue) should always be true for {left:?}, {right:?}"
755 );
756 }
757 }
758
759 #[test]
760 fn test_apply_operator_magic_rule_scenarios() {
761 let elf_magic = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
765 let elf_expected = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
766 assert!(apply_operator(&Operator::Equal, &elf_magic, &elf_expected));
767 assert!(!apply_operator(
768 &Operator::NotEqual,
769 &elf_magic,
770 &elf_expected
771 ));
772
773 let zip_magic = Value::Uint(0x504B_0304);
775 let zip_expected = Value::Uint(0x504B_0304);
776 assert!(apply_operator(&Operator::Equal, &zip_magic, &zip_expected));
777
778 let flags = Value::Uint(0b1101_0110);
780 let flag_mask = Value::Uint(0b0000_0010); assert!(apply_operator(&Operator::BitwiseAnd, &flags, &flag_mask));
782
783 let no_flag_mask = Value::Uint(0b0000_0001); assert!(!apply_operator(
785 &Operator::BitwiseAnd,
786 &flags,
787 &no_flag_mask
788 ));
789
790 let content = Value::String("#!/bin/bash".to_string());
792 let shebang = Value::String("#!/bin/bash".to_string());
793 assert!(apply_operator(&Operator::Equal, &content, &shebang));
794
795 let not_shebang = Value::String("#!/usr/bin/python".to_string());
796 assert!(apply_operator(&Operator::NotEqual, &content, ¬_shebang));
797
798 let version = Value::Uint(2);
800 let expected_version = Value::Uint(2);
801 let old_version = Value::Uint(1);
802 assert!(apply_operator(
803 &Operator::Equal,
804 &version,
805 &expected_version
806 ));
807 assert!(apply_operator(&Operator::NotEqual, &version, &old_version));
808 }
809
810 #[test]
811 fn test_apply_operator_edge_cases() {
812 let max_uint = Value::Uint(u64::MAX);
814 let min_signed = Value::Int(i64::MIN);
815 let max_signed = Value::Int(i64::MAX);
816
817 assert!(apply_operator(&Operator::Equal, &max_uint, &max_uint));
819 assert!(apply_operator(&Operator::Equal, &min_signed, &min_signed));
820 assert!(apply_operator(&Operator::Equal, &max_signed, &max_signed));
821
822 assert!(apply_operator(&Operator::NotEqual, &max_uint, &min_signed));
824 assert!(apply_operator(
825 &Operator::NotEqual,
826 &max_signed,
827 &min_signed
828 ));
829
830 assert!(apply_operator(
832 &Operator::BitwiseAnd,
833 &max_uint,
834 &Value::Uint(1)
835 ));
836 assert!(apply_operator(
837 &Operator::BitwiseAnd,
838 &min_signed,
839 &min_signed
840 ));
841
842 let empty_bytes = Value::Bytes(vec![]);
844 let empty_string = Value::String(String::new());
845 assert!(apply_operator(&Operator::Equal, &empty_bytes, &empty_bytes));
846 assert!(apply_operator(
847 &Operator::Equal,
848 &empty_string,
849 &empty_string
850 ));
851 assert!(apply_operator(
854 &Operator::Equal,
855 &empty_bytes,
856 &empty_string
857 ));
858
859 let zero_uint = Value::Uint(0);
861 let zero_signed = Value::Int(0);
862 assert!(!apply_operator(
863 &Operator::BitwiseAnd,
864 &zero_uint,
865 &Value::Uint(0xFF)
866 ));
867 assert!(!apply_operator(
868 &Operator::BitwiseAnd,
869 &zero_signed,
870 &Value::Int(0xFF)
871 ));
872 assert!(!apply_operator(
873 &Operator::NotEqual,
874 &zero_uint,
875 &zero_signed
876 )); }
878
879 #[test]
880 fn test_apply_operator_bitwise_xor() {
881 assert!(apply_operator(
882 &Operator::BitwiseXor,
883 &Value::Uint(0xFF),
884 &Value::Uint(0x0F)
885 ));
886 assert!(!apply_operator(
887 &Operator::BitwiseXor,
888 &Value::Uint(42),
889 &Value::Uint(42)
890 ));
891 assert!(!apply_operator(
892 &Operator::BitwiseXor,
893 &Value::String("x".to_string()),
894 &Value::Uint(1)
895 ));
896 }
897
898 #[test]
899 fn test_apply_operator_bitwise_not() {
900 assert!(apply_operator(
901 &Operator::BitwiseNot,
902 &Value::Uint(0),
903 &Value::Uint(u64::MAX)
904 ));
905 assert!(apply_operator(
906 &Operator::BitwiseNot,
907 &Value::Int(-1),
908 &Value::Int(0)
909 ));
910 assert!(!apply_operator(
911 &Operator::BitwiseNot,
912 &Value::Bytes(vec![0]),
913 &Value::Uint(0xFF)
914 ));
915 }
916
917 #[test]
918 fn test_apply_operator_any_value() {
919 assert!(apply_operator(
920 &Operator::AnyValue,
921 &Value::Uint(0),
922 &Value::Uint(0)
923 ));
924 assert!(apply_operator(
925 &Operator::AnyValue,
926 &Value::Int(42),
927 &Value::Int(0)
928 ));
929 assert!(apply_operator(
930 &Operator::AnyValue,
931 &Value::Bytes(vec![1, 2, 3]),
932 &Value::Bytes(vec![])
933 ));
934 assert!(apply_operator(
935 &Operator::AnyValue,
936 &Value::String("x".to_string()),
937 &Value::String("y".to_string())
938 ));
939 assert!(apply_operator(
940 &Operator::AnyValue,
941 &Value::Uint(1),
942 &Value::String(String::new())
943 ));
944 assert!(apply_operator(
945 &Operator::AnyValue,
946 &Value::Bytes(vec![]),
947 &Value::Bytes(vec![])
948 ));
949 }
950
951 #[test]
952 fn test_apply_operator_all_combinations() {
953 let operators = [
954 Operator::Equal,
955 Operator::NotEqual,
956 Operator::LessThan,
957 Operator::GreaterThan,
958 Operator::LessEqual,
959 Operator::GreaterEqual,
960 Operator::BitwiseAnd,
961 Operator::BitwiseAndMask(0xFF),
962 Operator::BitwiseXor,
963 Operator::BitwiseNot,
964 Operator::AnyValue,
965 ];
966 let values = [
967 Value::Uint(42),
968 Value::Int(-42),
969 Value::Bytes(vec![42]),
970 Value::String("42".to_string()),
971 ];
972
973 for operator in &operators {
975 for left in &values {
976 for right in &values {
977 let result = apply_operator(operator, left, right);
979
980 let expected = match operator {
982 Operator::Equal => apply_equal(left, right),
983 Operator::NotEqual => apply_not_equal(left, right),
984 Operator::LessThan => apply_less_than(left, right),
985 Operator::GreaterThan => apply_greater_than(left, right),
986 Operator::LessEqual => apply_less_equal(left, right),
987 Operator::GreaterEqual => apply_greater_equal(left, right),
988 Operator::BitwiseAnd => apply_bitwise_and(left, right),
989 Operator::BitwiseAndMask(mask) => {
990 apply_bitwise_and_mask(*mask, left, right)
991 }
992 Operator::BitwiseXor => apply_bitwise_xor(left, right),
993 Operator::BitwiseNot => apply_bitwise_not(left, right),
994 Operator::AnyValue => apply_any_value(left, right),
995 };
996
997 assert_eq!(
998 result, expected,
999 "apply_operator({operator:?}, {left:?}, {right:?}) should match individual function"
1000 );
1001 }
1002 }
1003 }
1004 }
1005}