use crate::core::xml_scan::{element_attr, element_text, first_of};
#[derive(Debug, Clone, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MessageMetadata {
pub message_id: Option<String>,
pub creation_date_time: Option<String>,
pub number_of_transactions: Option<String>,
pub amount: Option<String>,
pub currency: Option<String>,
pub value_date: Option<String>,
}
const AMOUNT_TAGS: &[&str] = &[
"TtlIntrBkSttlmAmt",
"IntrBkSttlmAmt",
"InstdAmt",
"EqvtAmt",
"TtlInstdAmt",
"Amt",
];
const DATE_TAGS: &[&str] = &["IntrBkSttlmDt", "ReqdExctnDt", "ReqdColltnDt", "IntrBkSttlmDtTm"];
pub fn extract(xml: &str) -> MessageMetadata {
let (amount, currency) = AMOUNT_TAGS
.iter()
.find_map(|&tag| {
element_text(xml, tag)
.filter(|v| !v.is_empty())
.map(|v| (Some(v), element_attr(xml, tag, "Ccy")))
})
.unwrap_or((None, None));
MessageMetadata {
message_id: element_text(xml, "MsgId").filter(|v| !v.is_empty()),
creation_date_time: element_text(xml, "CreDtTm").filter(|v| !v.is_empty()),
number_of_transactions: element_text(xml, "NbOfTxs").filter(|v| !v.is_empty()),
amount,
currency,
value_date: first_of(xml, DATE_TAGS).map(|(_, v)| v).filter(|v| !v.is_empty()),
}
}