use rust_iso20022::{MxNode, detect, read_business_message};
const MESSAGE: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
<BizMsgEnvlp>
<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<Fr><FIId><FinInstnId><BICFI>BANKBEBB</BICFI></FinInstnId></FIId></Fr>
<To><FIId><FinInstnId><BICFI>BANKDEFF</BICFI></FinInstnId></FIId></To>
<BizMsgIdr>MSG-2026-0001</BizMsgIdr>
<MsgDefIdr>pacs.008.001.08</MsgDefIdr>
<CreDt>2026-06-27T10:30:00Z</CreDt>
</AppHdr>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>ABC-2026-0001</MsgId>
<CreDtTm>2026-06-27T10:30:00Z</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<SttlmInf><SttlmMtd>INDA</SttlmMtd></SttlmInf>
</GrpHdr>
<CdtTrfTxInf>
<PmtId><EndToEndId>E2E-REF-001</EndToEndId></PmtId>
<IntrBkSttlmAmt Ccy="EUR">1234.56</IntrBkSttlmAmt>
<IntrBkSttlmDt>2026-06-30</IntrBkSttlmDt>
<Dbtr><Nm>Alice Inc.</Nm></Dbtr>
<Cdtr><Nm>Bob Ltd.</Nm></Cdtr>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
</BizMsgEnvlp>"#;
fn main() {
let id = detect(MESSAGE).expect("a recognisable ISO 20022 message");
println!(
"Message type : {} ({})",
id.message_name(),
id.business_area.description()
);
let bm = read_business_message(MESSAGE);
if let Some(h) = &bm.header {
println!("From / To : {} -> {}", opt(&h.from), opt(&h.to));
println!("Biz Msg Id : {}", opt(&h.biz_msg_idr));
}
let m = &bm.metadata;
println!("Group Msg Id : {}", opt(&m.message_id));
println!("Amount : {} {}", opt(&m.amount), opt(&m.currency));
println!("Value date : {}", opt(&m.value_date));
let doc = MxNode::parse(MESSAGE).expect("parseable tree");
let e2e = doc.find("EndToEndId").and_then(|n| n.text()).unwrap_or("-");
let dbtr = doc
.find("Dbtr")
.and_then(|n| n.get("Nm"))
.and_then(|n| n.text())
.unwrap_or("-");
let cdtr = doc
.find("Cdtr")
.and_then(|n| n.get("Nm"))
.and_then(|n| n.text())
.unwrap_or("-");
println!("End-to-end : {e2e}");
println!("Debtor : {dbtr}");
println!("Creditor : {cdtr}");
if let Some(amt) = doc.find("IntrBkSttlmAmt") {
println!(
"Settlement : {} {}",
amt.text().unwrap_or("-"),
amt.attr("Ccy").unwrap_or("-")
);
}
#[cfg(feature = "model-pacs")]
{
let parsed = rust_iso20022::parse(MESSAGE).expect("typed pacs parse");
let generated = parsed
.message()
.as_pacs_008_001_08()
.expect("pacs.008 generated value");
let _: &rust_iso20022::generated::pacs::pacs_008_001_08::Document = generated;
println!(
"Generated API: {} / {}",
parsed.message_id(),
parsed.root_element()
);
}
}
fn opt(v: &Option<String>) -> &str {
v.as_deref().unwrap_or("-")
}