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