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