1mod bitwise;
12mod comparison;
13mod equality;
14
15pub use bitwise::{
16 apply_bitwise_and, apply_bitwise_and_mask, apply_bitwise_not, apply_bitwise_not_with_width,
17 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);
646 match (&left, &right) {
647 (Value::Uint(a), Value::Uint(b)) => {
648 let expected = (a & b) != 0;
649 assert_eq!(
650 bitwise_result, expected,
651 "BitwiseAnd for Uint({a}) & Uint({b}) should be {expected}"
652 );
653 }
654 (Value::Int(a), Value::Int(b)) => {
655 #[allow(clippy::cast_sign_loss)]
656 let expected = ((*a as u64) & (*b as u64)) != 0;
657 assert_eq!(
658 bitwise_result, expected,
659 "BitwiseAnd for Int({a}) & Int({b}) should be {expected}"
660 );
661 }
662 (Value::Uint(a), Value::Int(b)) | (Value::Int(b), Value::Uint(a)) => {
663 #[allow(clippy::cast_sign_loss)]
664 let expected = (a & (*b as u64)) != 0;
665 assert_eq!(
666 bitwise_result, expected,
667 "BitwiseAnd for mixed Uint/Int should be {expected}"
668 );
669 }
670 _ => {
671 assert!(
673 !bitwise_result,
674 "BitwiseAnd should be false for non-integer types: {left:?} & {right:?}"
675 );
676 }
677 }
678 }
679 }
680
681 #[test]
682 fn test_apply_operator_consistency_with_individual_functions() {
683 let test_cases = vec![
684 (Value::Uint(42), Value::Uint(42)),
685 (Value::Uint(42), Value::Uint(24)),
686 (Value::Int(-100), Value::Int(-100)),
687 (Value::Int(100), Value::Int(-100)),
688 (
689 Value::String("test".to_string()),
690 Value::String("test".to_string()),
691 ),
692 (
693 Value::String("hello".to_string()),
694 Value::String("world".to_string()),
695 ),
696 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![1, 2, 3])),
697 (Value::Bytes(vec![1, 2, 3]), Value::Bytes(vec![4, 5, 6])),
698 (Value::Uint(42), Value::Int(42)),
700 (Value::Uint(42), Value::String("42".to_string())),
701 (Value::Int(42), Value::Bytes(vec![42])),
702 ];
703
704 for (left, right) in test_cases {
705 assert_eq!(
707 apply_operator(&Operator::Equal, &left, &right),
708 apply_equal(&left, &right),
709 "apply_operator(Equal) should match apply_equal for {left:?}, {right:?}"
710 );
711
712 assert_eq!(
713 apply_operator(&Operator::NotEqual, &left, &right),
714 apply_not_equal(&left, &right),
715 "apply_operator(NotEqual) should match apply_not_equal for {left:?}, {right:?}"
716 );
717
718 assert_eq!(
719 apply_operator(&Operator::BitwiseAnd, &left, &right),
720 apply_bitwise_and(&left, &right),
721 "apply_operator(BitwiseAnd) should match apply_bitwise_and for {left:?}, {right:?}"
722 );
723
724 assert_eq!(
725 apply_operator(&Operator::BitwiseXor, &left, &right),
726 apply_bitwise_xor(&left, &right),
727 "apply_operator(BitwiseXor) should match apply_bitwise_xor for {left:?}, {right:?}"
728 );
729
730 assert_eq!(
731 apply_operator(&Operator::BitwiseNot, &left, &right),
732 apply_bitwise_not(&left, &right),
733 "apply_operator(BitwiseNot) should match apply_bitwise_not for {left:?}, {right:?}"
734 );
735
736 assert!(
737 apply_operator(&Operator::AnyValue, &left, &right),
738 "apply_operator(AnyValue) should always be true for {left:?}, {right:?}"
739 );
740 }
741 }
742
743 #[test]
744 fn test_apply_operator_magic_rule_scenarios() {
745 let elf_magic = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
749 let elf_expected = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
750 assert!(apply_operator(&Operator::Equal, &elf_magic, &elf_expected));
751 assert!(!apply_operator(
752 &Operator::NotEqual,
753 &elf_magic,
754 &elf_expected
755 ));
756
757 let zip_magic = Value::Uint(0x504B_0304);
759 let zip_expected = Value::Uint(0x504B_0304);
760 assert!(apply_operator(&Operator::Equal, &zip_magic, &zip_expected));
761
762 let flags = Value::Uint(0b1101_0110);
764 let flag_mask = Value::Uint(0b0000_0010); assert!(apply_operator(&Operator::BitwiseAnd, &flags, &flag_mask));
766
767 let no_flag_mask = Value::Uint(0b0000_0001); assert!(!apply_operator(
769 &Operator::BitwiseAnd,
770 &flags,
771 &no_flag_mask
772 ));
773
774 let content = Value::String("#!/bin/bash".to_string());
776 let shebang = Value::String("#!/bin/bash".to_string());
777 assert!(apply_operator(&Operator::Equal, &content, &shebang));
778
779 let not_shebang = Value::String("#!/usr/bin/python".to_string());
780 assert!(apply_operator(&Operator::NotEqual, &content, ¬_shebang));
781
782 let version = Value::Uint(2);
784 let expected_version = Value::Uint(2);
785 let old_version = Value::Uint(1);
786 assert!(apply_operator(
787 &Operator::Equal,
788 &version,
789 &expected_version
790 ));
791 assert!(apply_operator(&Operator::NotEqual, &version, &old_version));
792 }
793
794 #[test]
795 fn test_apply_operator_edge_cases() {
796 let max_uint = Value::Uint(u64::MAX);
798 let min_signed = Value::Int(i64::MIN);
799 let max_signed = Value::Int(i64::MAX);
800
801 assert!(apply_operator(&Operator::Equal, &max_uint, &max_uint));
803 assert!(apply_operator(&Operator::Equal, &min_signed, &min_signed));
804 assert!(apply_operator(&Operator::Equal, &max_signed, &max_signed));
805
806 assert!(apply_operator(&Operator::NotEqual, &max_uint, &min_signed));
808 assert!(apply_operator(
809 &Operator::NotEqual,
810 &max_signed,
811 &min_signed
812 ));
813
814 assert!(apply_operator(
816 &Operator::BitwiseAnd,
817 &max_uint,
818 &Value::Uint(1)
819 ));
820 assert!(apply_operator(
821 &Operator::BitwiseAnd,
822 &min_signed,
823 &min_signed
824 ));
825
826 let empty_bytes = Value::Bytes(vec![]);
828 let empty_string = Value::String(String::new());
829 assert!(apply_operator(&Operator::Equal, &empty_bytes, &empty_bytes));
830 assert!(apply_operator(
831 &Operator::Equal,
832 &empty_string,
833 &empty_string
834 ));
835 assert!(apply_operator(
838 &Operator::Equal,
839 &empty_bytes,
840 &empty_string
841 ));
842
843 let zero_uint = Value::Uint(0);
845 let zero_signed = Value::Int(0);
846 assert!(!apply_operator(
847 &Operator::BitwiseAnd,
848 &zero_uint,
849 &Value::Uint(0xFF)
850 ));
851 assert!(!apply_operator(
852 &Operator::BitwiseAnd,
853 &zero_signed,
854 &Value::Int(0xFF)
855 ));
856 assert!(!apply_operator(
857 &Operator::NotEqual,
858 &zero_uint,
859 &zero_signed
860 )); }
862
863 #[test]
864 fn test_apply_operator_bitwise_xor() {
865 assert!(apply_operator(
866 &Operator::BitwiseXor,
867 &Value::Uint(0xFF),
868 &Value::Uint(0x0F)
869 ));
870 assert!(!apply_operator(
871 &Operator::BitwiseXor,
872 &Value::Uint(42),
873 &Value::Uint(42)
874 ));
875 assert!(!apply_operator(
876 &Operator::BitwiseXor,
877 &Value::String("x".to_string()),
878 &Value::Uint(1)
879 ));
880 }
881
882 #[test]
883 fn test_apply_operator_bitwise_not() {
884 assert!(apply_operator(
885 &Operator::BitwiseNot,
886 &Value::Uint(0),
887 &Value::Uint(u64::MAX)
888 ));
889 assert!(apply_operator(
890 &Operator::BitwiseNot,
891 &Value::Int(-1),
892 &Value::Int(0)
893 ));
894 assert!(!apply_operator(
895 &Operator::BitwiseNot,
896 &Value::Bytes(vec![0]),
897 &Value::Uint(0xFF)
898 ));
899 }
900
901 #[test]
902 fn test_apply_operator_any_value() {
903 assert!(apply_operator(
904 &Operator::AnyValue,
905 &Value::Uint(0),
906 &Value::Uint(0)
907 ));
908 assert!(apply_operator(
909 &Operator::AnyValue,
910 &Value::Int(42),
911 &Value::Int(0)
912 ));
913 assert!(apply_operator(
914 &Operator::AnyValue,
915 &Value::Bytes(vec![1, 2, 3]),
916 &Value::Bytes(vec![])
917 ));
918 assert!(apply_operator(
919 &Operator::AnyValue,
920 &Value::String("x".to_string()),
921 &Value::String("y".to_string())
922 ));
923 assert!(apply_operator(
924 &Operator::AnyValue,
925 &Value::Uint(1),
926 &Value::String(String::new())
927 ));
928 assert!(apply_operator(
929 &Operator::AnyValue,
930 &Value::Bytes(vec![]),
931 &Value::Bytes(vec![])
932 ));
933 }
934
935 #[test]
936 fn test_apply_operator_all_combinations() {
937 let operators = [
938 Operator::Equal,
939 Operator::NotEqual,
940 Operator::LessThan,
941 Operator::GreaterThan,
942 Operator::LessEqual,
943 Operator::GreaterEqual,
944 Operator::BitwiseAnd,
945 Operator::BitwiseAndMask(0xFF),
946 Operator::BitwiseXor,
947 Operator::BitwiseNot,
948 Operator::AnyValue,
949 ];
950 let values = [
951 Value::Uint(42),
952 Value::Int(-42),
953 Value::Bytes(vec![42]),
954 Value::String("42".to_string()),
955 ];
956
957 for operator in &operators {
959 for left in &values {
960 for right in &values {
961 let result = apply_operator(operator, left, right);
963
964 let expected = match operator {
966 Operator::Equal => apply_equal(left, right),
967 Operator::NotEqual => apply_not_equal(left, right),
968 Operator::LessThan => apply_less_than(left, right),
969 Operator::GreaterThan => apply_greater_than(left, right),
970 Operator::LessEqual => apply_less_equal(left, right),
971 Operator::GreaterEqual => apply_greater_equal(left, right),
972 Operator::BitwiseAnd => apply_bitwise_and(left, right),
973 Operator::BitwiseAndMask(mask) => {
974 apply_bitwise_and_mask(*mask, left, right)
975 }
976 Operator::BitwiseXor => apply_bitwise_xor(left, right),
977 Operator::BitwiseNot => apply_bitwise_not(left, right),
978 Operator::AnyValue => apply_any_value(left, right),
979 };
980
981 assert_eq!(
982 result, expected,
983 "apply_operator({operator:?}, {left:?}, {right:?}) should match individual function"
984 );
985 }
986 }
987 }
988 }
989}