mig_assembly/
diagnostic.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct StructureDiagnostic {
8 pub kind: StructureDiagnosticKind,
9 pub segment_id: String,
10 pub position: usize,
11 pub message: String,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
16pub enum StructureDiagnosticKind {
17 UnexpectedSegment,
19 MissingRequiredSegment,
22 MaxRepetitionsExceeded,
24 UnrecognizedQualifier,
28 MissingRequiredGroup,
30 GroupMaxRepetitionsExceeded,
32 SkippedUnknownSegment,
38 OrphanedGroupSegment,
46}
47
48impl std::fmt::Display for StructureDiagnostic {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(
51 f,
52 "[{:?}] {} at position {}: {}",
53 self.kind, self.segment_id, self.position, self.message
54 )
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn display_format_includes_all_fields() {
64 let diag = StructureDiagnostic {
65 kind: StructureDiagnosticKind::UnexpectedSegment,
66 segment_id: "BGM".to_string(),
67 position: 3,
68 message: "BGM not expected after UNH".to_string(),
69 };
70 let display = diag.to_string();
71 assert!(display.contains("BGM"), "display should contain segment_id");
72 assert!(display.contains("3"), "display should contain position");
73 assert!(
74 display.contains("BGM not expected after UNH"),
75 "display should contain message"
76 );
77 assert!(
78 display.contains("UnexpectedSegment"),
79 "display should contain kind"
80 );
81 }
82
83 #[test]
84 fn display_format_missing_required() {
85 let diag = StructureDiagnostic {
86 kind: StructureDiagnosticKind::MissingRequiredSegment,
87 segment_id: "IDE".to_string(),
88 position: 5,
89 message: "mandatory IDE segment missing in SG4".to_string(),
90 };
91 let display = diag.to_string();
92 assert_eq!(
93 display,
94 "[MissingRequiredSegment] IDE at position 5: mandatory IDE segment missing in SG4"
95 );
96 }
97
98 #[test]
99 fn serialization_roundtrip() {
100 let diag = StructureDiagnostic {
101 kind: StructureDiagnosticKind::MaxRepetitionsExceeded,
102 segment_id: "RFF".to_string(),
103 position: 12,
104 message: "RFF exceeded max repetitions of 5".to_string(),
105 };
106 let json = serde_json::to_string(&diag).expect("serialize");
107 let roundtripped: StructureDiagnostic = serde_json::from_str(&json).expect("deserialize");
108 assert_eq!(
109 roundtripped.kind,
110 StructureDiagnosticKind::MaxRepetitionsExceeded
111 );
112 assert_eq!(roundtripped.segment_id, "RFF");
113 assert_eq!(roundtripped.position, 12);
114 assert_eq!(roundtripped.message, "RFF exceeded max repetitions of 5");
115 }
116
117 #[test]
118 fn serialization_roundtrip_unrecognized_qualifier() {
119 let diag = StructureDiagnostic {
120 kind: StructureDiagnosticKind::UnrecognizedQualifier,
121 segment_id: "LOC".to_string(),
122 position: 7,
123 message: "qualifier Z99 not recognized for LOC in SG5".to_string(),
124 };
125 let json = serde_json::to_string(&diag).expect("serialize");
126 let roundtripped: StructureDiagnostic = serde_json::from_str(&json).expect("deserialize");
127 assert_eq!(
128 roundtripped.kind,
129 StructureDiagnosticKind::UnrecognizedQualifier
130 );
131 assert_eq!(roundtripped.segment_id, "LOC");
132 assert_eq!(roundtripped.position, 7);
133 assert_eq!(
134 roundtripped.message,
135 "qualifier Z99 not recognized for LOC in SG5"
136 );
137 }
138}