mx_message/plugin/
common.rs1use crate::message_registry;
7use dataflow_rs::engine::error::{DataflowError, Result};
8use serde_json::Value;
9
10pub fn map_document_element_to_message_type(element_name: &str) -> Result<String> {
19 if let Some(msg_type) = message_registry::element_to_message_type(element_name) {
21 return Ok(msg_type.to_string());
22 }
23
24 let message_type = match element_name {
26 "FinInstnCdtTrf" => "pacs.009", "Rct" => "camt.025", "ClmNonRct" | "ClaimNonReceiptV07" => "camt.027", _ => {
30 return Err(DataflowError::Validation(format!(
31 "Unknown document element: {}",
32 element_name
33 )));
34 }
35 };
36 Ok(message_type.to_string())
37}
38
39pub fn extract_message_type(data: &Value) -> Result<String> {
53 if let Some(mt) = data.get("message_type").and_then(Value::as_str) {
55 return Ok(mt.to_string());
56 }
57
58 if let Some(doc) = data.get("Document") {
60 if let Some(obj) = doc.as_object()
62 && let Some(first_key) = obj.keys().next()
63 {
64 return map_document_element_to_message_type(first_key);
66 }
67 }
68
69 Err(DataflowError::Validation(
70 "Could not determine message type from parsed data".to_string(),
71 ))
72}
73
74pub fn extract_message_type_from_xml(xml_str: &str) -> Result<String> {
86 let xml_str = xml_str.trim();
87
88 if let Some(doc_start) = xml_str.find("<Document") {
90 if let Some(doc_end) = xml_str[doc_start..].find('>') {
92 let after_doc = &xml_str[doc_start + doc_end + 1..];
93
94 if let Some(elem_start) = after_doc.find('<')
96 && after_doc.as_bytes()[elem_start + 1] != b'/'
97 {
98 let elem_name_start = elem_start + 1;
99 let elem_name_end = after_doc[elem_name_start..]
101 .find([' ', '>', '/'])
102 .map(|i| elem_name_start + i)
103 .unwrap_or(after_doc.len());
104
105 let element_name = &after_doc[elem_name_start..elem_name_end];
106 let element_name = if let Some(colon_pos) = element_name.rfind(':') {
108 &element_name[colon_pos + 1..]
109 } else {
110 element_name
111 };
112
113 return map_document_element_to_message_type(element_name);
114 }
115 }
116 }
117
118 Err(DataflowError::Validation(
119 "Could not extract message type from XML".to_string(),
120 ))
121}
122
123pub fn extract_mx_content(
139 message_data: &Value,
140 field_name: &str,
141 message_payload: &Value,
142) -> Result<String> {
143 if field_name == "payload" {
144 if let Some(s) = message_payload.as_str() {
146 Ok(s.to_string())
147 } else {
148 Ok(message_payload.to_string().trim_matches('"').to_string())
150 }
151 } else {
152 let field_value = message_data.get(field_name).ok_or_else(|| {
154 DataflowError::Validation(format!(
155 "MX message field '{}' not found in message data",
156 field_name
157 ))
158 })?;
159
160 if let Some(mx_msg) = field_value.get("mx_message").and_then(Value::as_str) {
162 Ok(mx_msg.to_string())
163 } else if let Some(s) = field_value.as_str() {
164 Ok(s.to_string())
166 } else {
167 Err(DataflowError::Validation(format!(
168 "Field '{}' does not contain a valid MX message",
169 field_name
170 )))
171 }
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178 use serde_json::json;
179
180 #[test]
181 fn test_map_document_element_to_message_type() {
182 assert_eq!(
183 map_document_element_to_message_type("FIToFICstmrCdtTrf").unwrap(),
184 "pacs.008"
185 );
186 assert_eq!(
187 map_document_element_to_message_type("BkToCstmrStmt").unwrap(),
188 "camt.053"
189 );
190 assert_eq!(
191 map_document_element_to_message_type("CstmrCdtTrfInitn").unwrap(),
192 "pain.001"
193 );
194 assert!(map_document_element_to_message_type("UnknownElement").is_err());
195 }
196
197 #[test]
198 fn test_extract_message_type() {
199 let data = json!({"message_type": "pacs.008", "other": "data"});
201 assert_eq!(extract_message_type(&data).unwrap(), "pacs.008");
202
203 let data = json!({
205 "Document": {
206 "FIToFICstmrCdtTrf": {
207 "GrpHdr": {}
208 }
209 }
210 });
211 assert_eq!(extract_message_type(&data).unwrap(), "pacs.008");
212
213 let data = json!({"other": "data"});
215 assert!(extract_message_type(&data).is_err());
216 }
217
218 #[test]
219 fn test_extract_mx_content() {
220 let payload = json!("test content");
221 let data = json!({
222 "field1": "direct string",
223 "field2": {
224 "mx_message": "nested message"
225 }
226 });
227
228 assert_eq!(
230 extract_mx_content(&data, "payload", &payload).unwrap(),
231 "test content"
232 );
233
234 assert_eq!(
236 extract_mx_content(&data, "field1", &payload).unwrap(),
237 "direct string"
238 );
239
240 assert_eq!(
242 extract_mx_content(&data, "field2", &payload).unwrap(),
243 "nested message"
244 );
245
246 assert!(extract_mx_content(&data, "missing", &payload).is_err());
248 }
249}