1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//! Bidirectional MT ↔ MX translation for ISO 20022 messages.
//!
//! This crate translates between SWIFT MT FIN messages and their
//! corresponding ISO 20022 MX (XML) representations. It provides:
//!
//! - A SWIFT MT message parser ([`mt`]) that decomposes a raw MT
//! message into its block structure (blocks 1, 2, 3, 4, 5) and
//! then into typed field structs ([`mt::fields::mt103::Mt103`],
//! [`mt::fields::mt202::Mt202`], [`mt::fields::mt940::Mt940`]).
//! - Translation helpers in [`mappings`] that convert each parsed
//! MT struct into the corresponding pacs / camt `Document` from
//! `mx20022-model`, and back.
//! - A [`mappings::charset`] module covering SWIFT FIN character-set
//! conversion and SWIFT-MT line-wrapping.
//! - Translation result and error types
//! ([`mappings::TranslationResult`], [`mappings::TranslationError`])
//! that distinguish hard failures from data-loss warnings
//! ([`mappings::TranslationWarning`]).
//!
//! # Supported message-type pairs
//!
//! | Direction | Source | Target |
//! |-----------|------------------|---------------------|
//! | MT → MX | MT103 | pacs.008.001.13 |
//! | MX → MT | pacs.008.001.13 | MT103 |
//! | MT → MX | MT202 | pacs.009.001.10 |
//! | MX → MT | pacs.009.001.10 | MT202 |
//! | MT → MX | MT940 | camt.053.001.11 |
//! | MX → MT | camt.053.001.11 | MT940 |
//!
//! Other MT message types (MT202COV, MT900, MT910, MT942) and other
//! pacs / camt versions are not yet wired up.
//!
//! # Quick start: MT103 → pacs.008.001.13
//!
//! ```
//! use mx20022_translate::mappings::mt103_to_pacs008::mt103_to_pacs008;
//! use mx20022_translate::mt::{self, fields::mt103::parse_mt103};
//!
//! let raw = "\
//! {1:F01BANKBEBBAXXX0000000000}\
//! {2:I103BANKDEFFXXXXN}\
//! {3:{108:MYREF}}\
//! {4:\n\
//! :20:REF123\n\
//! :23B:CRED\n\
//! :32A:230615EUR1000,00\n\
//! :50K:ACME CORP\n\
//! :59:JANE SMITH\n\
//! :71A:SHA\n\
//! -}\
//! {5:{CHK:ABCDEF1234}}";
//!
//! // Step 1: parse the raw MT into block structure.
//! let msg = mt::parse(raw).unwrap();
//! assert_eq!(msg.message_type(), Some("103"));
//!
//! // Step 2: parse Block 4 into typed MT103 fields.
//! let mt103 = parse_mt103(&msg.block4).unwrap();
//! assert_eq!(mt103.senders_reference, "REF123");
//!
//! // Step 3: translate to pacs.008.001.13.
//! let result = mt103_to_pacs008(&mt103, "MSG-1", "2023-06-15T10:00:00").unwrap();
//! let doc = &result.message;
//! let tx = &doc.fi_to_fi_cstmr_cdt_trf.cdt_trf_tx_inf[0];
//! assert_eq!(tx.intr_bk_sttlm_amt.value.0, "1000.00");
//! assert_eq!(tx.intr_bk_sttlm_amt.ccy.0, "EUR");
//!
//! // result.warnings carries any data-loss notes, e.g. when an MT
//! // field has no clean pacs.008 equivalent.
//! for w in &result.warnings.warnings {
//! eprintln!("{}: {}", w.field, w.message);
//! }
//! ```
//!
//! # Quick start: pacs.008.001.13 → MT103
//!
//! `pacs008_to_mt103` requires the source pacs.008 to carry a BICFI
//! or party name on `DbtrAgt` and `CdtrAgt` (the BICs that go into
//! the MT message header). The fixture below adds `:52A:` and
//! `:57A:` to the source MT103 so the round-trip carries that data
//! through.
//!
//! ```
//! # use mx20022_translate::mappings::{mt103_to_pacs008::mt103_to_pacs008, pacs008_to_mt103::pacs008_to_mt103};
//! # use mx20022_translate::mt::{self, fields::mt103::parse_mt103};
//! # let raw = "{1:F01BANKBEBBAXXX0000000000}{2:I103BANKDEFFXXXXN}{3:{108:R}}{4:\n:20:R\n:23B:CRED\n:32A:230615EUR1,00\n:52A:BANKBEBBAXXX\n:50K:A\n:57A:BANKDEFFXXXX\n:59:B\n:71A:SHA\n-}{5:{CHK:0}}";
//! # let mt103 = parse_mt103(&mt::parse(raw).unwrap().block4).unwrap();
//! # let doc = mt103_to_pacs008(&mt103, "M", "2023-06-15T10:00:00").unwrap().message;
//! let result = pacs008_to_mt103(&doc).unwrap();
//! assert!(result.message.contains(":20:"));
//! assert!(result.message.contains(":32A:"));
//! ```
//!
//! See the `roundtrip` and `translate_mt103` examples in the umbrella
//! `mx20022` crate for end-to-end demos that include XML
//! serialization.