1use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
13pub enum OffsetSpec {
14 Absolute(i64),
28
29 Indirect {
47 base_offset: i64,
49 pointer_type: TypeKind,
51 adjustment: i64,
53 endian: Endianness,
55 },
56
57 Relative(i64),
67
68 FromEnd(i64),
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
82pub enum TypeKind {
83 Byte {
85 signed: bool,
87 },
88 Short {
90 endian: Endianness,
92 signed: bool,
94 },
95 Long {
97 endian: Endianness,
99 signed: bool,
101 },
102 Quad {
113 endian: Endianness,
115 signed: bool,
117 },
118 String {
120 max_length: Option<usize>,
122 },
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
127pub enum Operator {
128 Equal,
139 NotEqual,
150 LessThan,
161 GreaterThan,
172 LessEqual,
183 GreaterEqual,
194 BitwiseAnd,
205 BitwiseAndMask(u64),
216}
217
218#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
220pub enum Value {
221 Uint(u64),
223 Int(i64),
225 Bytes(Vec<u8>),
227 String(String),
229}
230
231#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
233pub enum Endianness {
234 Little,
236 Big,
238 Native,
240}
241
242#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
259pub enum StrengthModifier {
260 Add(i32),
262 Subtract(i32),
264 Multiply(i32),
266 Divide(i32),
268 Set(i32),
270}
271
272#[derive(Debug, Clone, Serialize, Deserialize)]
274pub struct MagicRule {
275 pub offset: OffsetSpec,
277 pub typ: TypeKind,
279 pub op: Operator,
281 pub value: Value,
283 pub message: String,
285 pub children: Vec<MagicRule>,
287 pub level: u32,
289 pub strength_modifier: Option<StrengthModifier>,
291}
292
293#[cfg(test)]
302mod tests {
303 use super::*;
304
305 #[test]
306 fn test_offset_spec_absolute() {
307 let offset = OffsetSpec::Absolute(42);
308 assert_eq!(offset, OffsetSpec::Absolute(42));
309
310 let negative = OffsetSpec::Absolute(-10);
312 assert_eq!(negative, OffsetSpec::Absolute(-10));
313 }
314
315 #[test]
316 fn test_offset_spec_indirect() {
317 let indirect = OffsetSpec::Indirect {
318 base_offset: 0x20,
319 pointer_type: TypeKind::Long {
320 endian: Endianness::Little,
321 signed: false,
322 },
323 adjustment: 4,
324 endian: Endianness::Little,
325 };
326
327 match indirect {
328 OffsetSpec::Indirect {
329 base_offset,
330 adjustment,
331 ..
332 } => {
333 assert_eq!(base_offset, 0x20);
334 assert_eq!(adjustment, 4);
335 }
336 _ => panic!("Expected Indirect variant"),
337 }
338 }
339
340 #[test]
341 fn test_offset_spec_relative() {
342 let relative = OffsetSpec::Relative(8);
343 assert_eq!(relative, OffsetSpec::Relative(8));
344
345 let negative_relative = OffsetSpec::Relative(-4);
347 assert_eq!(negative_relative, OffsetSpec::Relative(-4));
348 }
349
350 #[test]
351 fn test_offset_spec_from_end() {
352 let from_end = OffsetSpec::FromEnd(-16);
353 assert_eq!(from_end, OffsetSpec::FromEnd(-16));
354
355 let positive_from_end = OffsetSpec::FromEnd(8);
357 assert_eq!(positive_from_end, OffsetSpec::FromEnd(8));
358 }
359
360 #[test]
361 fn test_offset_spec_debug() {
362 let offset = OffsetSpec::Absolute(100);
363 let debug_str = format!("{offset:?}");
364 assert!(debug_str.contains("Absolute"));
365 assert!(debug_str.contains("100"));
366 }
367
368 #[test]
369 fn test_offset_spec_clone() {
370 let original = OffsetSpec::Indirect {
371 base_offset: 0x10,
372 pointer_type: TypeKind::Short {
373 endian: Endianness::Big,
374 signed: true,
375 },
376 adjustment: -2,
377 endian: Endianness::Big,
378 };
379
380 let cloned = original.clone();
381 assert_eq!(original, cloned);
382 }
383
384 #[test]
385 fn test_offset_spec_serialization() {
386 let offset = OffsetSpec::Absolute(42);
387
388 let json = serde_json::to_string(&offset).expect("Failed to serialize");
390 let deserialized: OffsetSpec = serde_json::from_str(&json).expect("Failed to deserialize");
391
392 assert_eq!(offset, deserialized);
393 }
394
395 #[test]
396 fn test_offset_spec_indirect_serialization() {
397 let indirect = OffsetSpec::Indirect {
398 base_offset: 0x100,
399 pointer_type: TypeKind::Long {
400 endian: Endianness::Native,
401 signed: false,
402 },
403 adjustment: 12,
404 endian: Endianness::Native,
405 };
406
407 let json = serde_json::to_string(&indirect).expect("Failed to serialize");
409 let deserialized: OffsetSpec = serde_json::from_str(&json).expect("Failed to deserialize");
410
411 assert_eq!(indirect, deserialized);
412 }
413
414 #[test]
415 fn test_all_offset_spec_variants() {
416 let variants = [
417 OffsetSpec::Absolute(0),
418 OffsetSpec::Absolute(-100),
419 OffsetSpec::Indirect {
420 base_offset: 0x20,
421 pointer_type: TypeKind::Byte { signed: true },
422 adjustment: 0,
423 endian: Endianness::Little,
424 },
425 OffsetSpec::Relative(50),
426 OffsetSpec::Relative(-25),
427 OffsetSpec::FromEnd(-8),
428 OffsetSpec::FromEnd(4),
429 ];
430
431 for (i, variant) in variants.iter().enumerate() {
433 for (j, other) in variants.iter().enumerate() {
434 if i != j {
435 assert_ne!(
436 variant, other,
437 "Variants at indices {i} and {j} should be different"
438 );
439 }
440 }
441 }
442 }
443
444 #[test]
445 fn test_endianness_variants() {
446 let endianness_values = vec![Endianness::Little, Endianness::Big, Endianness::Native];
447
448 for endian in endianness_values {
449 let indirect = OffsetSpec::Indirect {
450 base_offset: 0,
451 pointer_type: TypeKind::Long {
452 endian,
453 signed: false,
454 },
455 adjustment: 0,
456 endian,
457 };
458
459 match indirect {
461 OffsetSpec::Indirect {
462 endian: actual_endian,
463 ..
464 } => {
465 assert_eq!(endian, actual_endian);
466 }
467 _ => panic!("Expected Indirect variant"),
468 }
469 }
470 }
471
472 #[test]
474 fn test_value_uint() {
475 let value = Value::Uint(42);
476 assert_eq!(value, Value::Uint(42));
477
478 let large_value = Value::Uint(u64::MAX);
480 assert_eq!(large_value, Value::Uint(u64::MAX));
481 }
482
483 #[test]
484 fn test_value_int() {
485 let positive = Value::Int(100);
486 assert_eq!(positive, Value::Int(100));
487
488 let negative = Value::Int(-50);
489 assert_eq!(negative, Value::Int(-50));
490
491 let max_int = Value::Int(i64::MAX);
493 let min_int = Value::Int(i64::MIN);
494 assert_eq!(max_int, Value::Int(i64::MAX));
495 assert_eq!(min_int, Value::Int(i64::MIN));
496 }
497
498 #[test]
499 fn test_value_bytes() {
500 let empty_bytes = Value::Bytes(vec![]);
501 assert_eq!(empty_bytes, Value::Bytes(vec![]));
502
503 let some_bytes = Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]);
504 assert_eq!(some_bytes, Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]));
505
506 let other_bytes = Value::Bytes(vec![0x50, 0x4b, 0x03, 0x04]);
508 assert_ne!(some_bytes, other_bytes);
509 }
510
511 #[test]
512 fn test_value_string() {
513 let empty_string = Value::String(String::new());
514 assert_eq!(empty_string, Value::String(String::new()));
515
516 let hello = Value::String("Hello, World!".to_string());
517 assert_eq!(hello, Value::String("Hello, World!".to_string()));
518
519 let unicode = Value::String("🦀 Rust".to_string());
521 assert_eq!(unicode, Value::String("🦀 Rust".to_string()));
522 }
523
524 #[test]
525 fn test_value_comparison() {
526 let uint_val = Value::Uint(42);
528 let int_val = Value::Int(42);
529 let bytes_val = Value::Bytes(vec![42]);
530 let string_val = Value::String("42".to_string());
531
532 assert_ne!(uint_val, int_val);
533 assert_ne!(uint_val, bytes_val);
534 assert_ne!(uint_val, string_val);
535 assert_ne!(int_val, bytes_val);
536 assert_ne!(int_val, string_val);
537 assert_ne!(bytes_val, string_val);
538 }
539
540 #[test]
541 fn test_value_debug() {
542 let uint_val = Value::Uint(123);
543 let debug_str = format!("{uint_val:?}");
544 assert!(debug_str.contains("Uint"));
545 assert!(debug_str.contains("123"));
546
547 let string_val = Value::String("test".to_string());
548 let debug_str = format!("{string_val:?}");
549 assert!(debug_str.contains("String"));
550 assert!(debug_str.contains("test"));
551 }
552
553 #[test]
554 fn test_value_clone() {
555 let original = Value::Bytes(vec![1, 2, 3, 4]);
556 let cloned = original.clone();
557 assert_eq!(original, cloned);
558
559 match (original, cloned) {
561 (Value::Bytes(orig_bytes), Value::Bytes(cloned_bytes)) => {
562 assert_eq!(orig_bytes, cloned_bytes);
563 }
565 _ => panic!("Expected Bytes variants"),
566 }
567 }
568
569 #[test]
570 fn test_value_serialization() {
571 let values = vec![
572 Value::Uint(42),
573 Value::Int(-100),
574 Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]),
575 Value::String("ELF executable".to_string()),
576 ];
577
578 for value in values {
579 let json = serde_json::to_string(&value).expect("Failed to serialize Value");
581 let deserialized: Value =
582 serde_json::from_str(&json).expect("Failed to deserialize Value");
583 assert_eq!(value, deserialized);
584 }
585 }
586
587 #[test]
588 fn test_value_serialization_edge_cases() {
589 let empty_bytes = Value::Bytes(vec![]);
591 let json = serde_json::to_string(&empty_bytes).expect("Failed to serialize empty bytes");
592 let deserialized: Value =
593 serde_json::from_str(&json).expect("Failed to deserialize empty bytes");
594 assert_eq!(empty_bytes, deserialized);
595
596 let empty_string = Value::String(String::new());
597 let json = serde_json::to_string(&empty_string).expect("Failed to serialize empty string");
598 let deserialized: Value =
599 serde_json::from_str(&json).expect("Failed to deserialize empty string");
600 assert_eq!(empty_string, deserialized);
601
602 let max_uint = Value::Uint(u64::MAX);
604 let json = serde_json::to_string(&max_uint).expect("Failed to serialize max uint");
605 let deserialized: Value =
606 serde_json::from_str(&json).expect("Failed to deserialize max uint");
607 assert_eq!(max_uint, deserialized);
608
609 let min_int = Value::Int(i64::MIN);
610 let json = serde_json::to_string(&min_int).expect("Failed to serialize min int");
611 let deserialized: Value =
612 serde_json::from_str(&json).expect("Failed to deserialize min int");
613 assert_eq!(min_int, deserialized);
614 }
615
616 #[test]
618 fn test_type_kind_byte() {
619 let byte_type = TypeKind::Byte { signed: true };
620 assert_eq!(byte_type, TypeKind::Byte { signed: true });
621 }
622
623 #[test]
624 fn test_type_kind_short() {
625 let short_little_endian = TypeKind::Short {
626 endian: Endianness::Little,
627 signed: false,
628 };
629 let short_big_endian = TypeKind::Short {
630 endian: Endianness::Big,
631 signed: true,
632 };
633
634 assert_ne!(short_little_endian, short_big_endian);
635 assert_eq!(short_little_endian, short_little_endian.clone());
636 }
637
638 #[test]
639 fn test_type_kind_long() {
640 let long_native = TypeKind::Long {
641 endian: Endianness::Native,
642 signed: true,
643 };
644
645 match long_native {
646 TypeKind::Long { endian, signed } => {
647 assert_eq!(endian, Endianness::Native);
648 assert!(signed);
649 }
650 _ => panic!("Expected Long variant"),
651 }
652 }
653
654 #[test]
655 fn test_type_kind_string() {
656 let unlimited_string = TypeKind::String { max_length: None };
657 let limited_string = TypeKind::String {
658 max_length: Some(256),
659 };
660
661 assert_ne!(unlimited_string, limited_string);
662 assert_eq!(unlimited_string, unlimited_string.clone());
663 }
664
665 #[test]
666 fn test_type_kind_serialization() {
667 let types = vec![
668 TypeKind::Byte { signed: true },
669 TypeKind::Short {
670 endian: Endianness::Little,
671 signed: false,
672 },
673 TypeKind::Long {
674 endian: Endianness::Big,
675 signed: true,
676 },
677 TypeKind::Quad {
678 endian: Endianness::Little,
679 signed: false,
680 },
681 TypeKind::Quad {
682 endian: Endianness::Big,
683 signed: true,
684 },
685 TypeKind::String { max_length: None },
686 TypeKind::String {
687 max_length: Some(128),
688 },
689 ];
690
691 for typ in types {
692 let json = serde_json::to_string(&typ).expect("Failed to serialize TypeKind");
693 let deserialized: TypeKind =
694 serde_json::from_str(&json).expect("Failed to deserialize TypeKind");
695 assert_eq!(typ, deserialized);
696 }
697 }
698
699 #[test]
701 fn test_operator_variants() {
702 let operators = [Operator::Equal, Operator::NotEqual, Operator::BitwiseAnd];
703
704 for (i, op) in operators.iter().enumerate() {
705 for (j, other) in operators.iter().enumerate() {
706 if i == j {
707 assert_eq!(op, other);
708 } else {
709 assert_ne!(op, other);
710 }
711 }
712 }
713 }
714
715 #[test]
716 fn test_operator_serialization() {
717 let operators = vec![Operator::Equal, Operator::NotEqual, Operator::BitwiseAnd];
718
719 for op in operators {
720 let json = serde_json::to_string(&op).expect("Failed to serialize Operator");
721 let deserialized: Operator =
722 serde_json::from_str(&json).expect("Failed to deserialize Operator");
723 assert_eq!(op, deserialized);
724 }
725 }
726
727 #[test]
729 fn test_magic_rule_creation() {
730 let rule = MagicRule {
731 offset: OffsetSpec::Absolute(0),
732 typ: TypeKind::Byte { signed: true },
733 op: Operator::Equal,
734 value: Value::Uint(0x7f),
735 message: "ELF magic".to_string(),
736 children: vec![],
737 level: 0,
738 strength_modifier: None,
739 };
740
741 assert_eq!(rule.message, "ELF magic");
742 assert_eq!(rule.level, 0);
743 assert!(rule.children.is_empty());
744 }
745
746 #[test]
747 fn test_magic_rule_with_children() {
748 let child_rule = MagicRule {
749 offset: OffsetSpec::Absolute(4),
750 typ: TypeKind::Byte { signed: true },
751 op: Operator::Equal,
752 value: Value::Uint(1),
753 message: "32-bit".to_string(),
754 children: vec![],
755 level: 1,
756 strength_modifier: None,
757 };
758
759 let parent_rule = MagicRule {
760 offset: OffsetSpec::Absolute(0),
761 typ: TypeKind::Long {
762 endian: Endianness::Little,
763 signed: false,
764 },
765 op: Operator::Equal,
766 value: Value::Bytes(vec![0x7f, 0x45, 0x4c, 0x46]),
767 message: "ELF executable".to_string(),
768 children: vec![child_rule],
769 level: 0,
770 strength_modifier: None,
771 };
772
773 assert_eq!(parent_rule.children.len(), 1);
774 assert_eq!(parent_rule.children[0].level, 1);
775 assert_eq!(parent_rule.children[0].message, "32-bit");
776 }
777
778 #[test]
779 fn test_magic_rule_serialization() {
780 let rule = MagicRule {
781 offset: OffsetSpec::Absolute(16),
782 typ: TypeKind::Short {
783 endian: Endianness::Little,
784 signed: false,
785 },
786 op: Operator::NotEqual,
787 value: Value::Uint(0),
788 message: "Non-zero short value".to_string(),
789 children: vec![],
790 level: 2,
791 strength_modifier: None,
792 };
793
794 let json = serde_json::to_string(&rule).expect("Failed to serialize MagicRule");
795 let deserialized: MagicRule =
796 serde_json::from_str(&json).expect("Failed to deserialize MagicRule");
797
798 assert_eq!(rule.message, deserialized.message);
799 assert_eq!(rule.level, deserialized.level);
800 assert_eq!(rule.children.len(), deserialized.children.len());
801 }
802
803 #[test]
805 fn test_strength_modifier_variants() {
806 let add = StrengthModifier::Add(10);
807 let sub = StrengthModifier::Subtract(5);
808 let mul = StrengthModifier::Multiply(2);
809 let div = StrengthModifier::Divide(2);
810 let set = StrengthModifier::Set(50);
811
812 assert_eq!(add, StrengthModifier::Add(10));
814 assert_eq!(sub, StrengthModifier::Subtract(5));
815 assert_eq!(mul, StrengthModifier::Multiply(2));
816 assert_eq!(div, StrengthModifier::Divide(2));
817 assert_eq!(set, StrengthModifier::Set(50));
818
819 assert_ne!(add, sub);
821 assert_ne!(mul, div);
822 assert_ne!(set, add);
823 }
824
825 #[test]
826 fn test_strength_modifier_negative_values() {
827 let add_negative = StrengthModifier::Add(-10);
828 let sub_negative = StrengthModifier::Subtract(-5);
829 let set_negative = StrengthModifier::Set(-50);
830
831 assert_eq!(add_negative, StrengthModifier::Add(-10));
832 assert_eq!(sub_negative, StrengthModifier::Subtract(-5));
833 assert_eq!(set_negative, StrengthModifier::Set(-50));
834 }
835
836 #[test]
837 fn test_strength_modifier_serialization() {
838 let modifiers = vec![
839 StrengthModifier::Add(10),
840 StrengthModifier::Subtract(5),
841 StrengthModifier::Multiply(2),
842 StrengthModifier::Divide(3),
843 StrengthModifier::Set(100),
844 ];
845
846 for modifier in modifiers {
847 let json =
848 serde_json::to_string(&modifier).expect("Failed to serialize StrengthModifier");
849 let deserialized: StrengthModifier =
850 serde_json::from_str(&json).expect("Failed to deserialize StrengthModifier");
851 assert_eq!(modifier, deserialized);
852 }
853 }
854
855 #[test]
856 fn test_strength_modifier_debug() {
857 let modifier = StrengthModifier::Add(25);
858 let debug_str = format!("{modifier:?}");
859 assert!(debug_str.contains("Add"));
860 assert!(debug_str.contains("25"));
861 }
862
863 #[test]
864 fn test_strength_modifier_clone() {
865 let original = StrengthModifier::Multiply(4);
866 let cloned = original;
867 assert_eq!(original, cloned);
868 }
869
870 #[test]
871 fn test_magic_rule_with_strength_modifier() {
872 let rule = MagicRule {
873 offset: OffsetSpec::Absolute(0),
874 typ: TypeKind::Byte { signed: true },
875 op: Operator::Equal,
876 value: Value::Uint(0x7f),
877 message: "ELF magic".to_string(),
878 children: vec![],
879 level: 0,
880 strength_modifier: Some(StrengthModifier::Add(20)),
881 };
882
883 assert_eq!(rule.strength_modifier, Some(StrengthModifier::Add(20)));
884
885 let json = serde_json::to_string(&rule).expect("Failed to serialize MagicRule");
887 let deserialized: MagicRule =
888 serde_json::from_str(&json).expect("Failed to deserialize MagicRule");
889 assert_eq!(rule.strength_modifier, deserialized.strength_modifier);
890 }
891
892 #[test]
893 fn test_magic_rule_without_strength_modifier() {
894 let rule = MagicRule {
895 offset: OffsetSpec::Absolute(0),
896 typ: TypeKind::Byte { signed: true },
897 op: Operator::Equal,
898 value: Value::Uint(0x7f),
899 message: "ELF magic".to_string(),
900 children: vec![],
901 level: 0,
902 strength_modifier: None,
903 };
904
905 assert_eq!(rule.strength_modifier, None);
906 }
907}